www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Extending Objective-C from D.

reply Jeremie Pelletier <jeremiep gmail.com> writes:
Hello, I'm trying to see if I can write a full Cocoa app in D, 
and I'm having trouble creating D classes when the underlying 
Objective-C interfaces have methods.

It works for the app delegate because it needs to override them, 
but for other classes the compiler says the Objective-C methods 
aren't implemented in the D subclass.

I was successful in getting a simple application to boot with 
console errors about a missing NIB file. Its impressive how much 
you can get done so far :D

Now I'm trying to manually create the app and the delegate, 
completely bypassing NSApplicationMain with mixed success. Here's 
the main function:

     auto me = new MyApplication;
     auto dg = new MyAppDelegate;
     me.setDelegate(dg);
     me.run();

I even asserted after instantiating MyApplication it is identical 
to NSApplication.sharedApplication (using the objc_lookUpClass 
trick to emulate static calls) and they're the same value. The 
delegate also creates correctly, just like it did through 
NSApplicationMain reading the Info.plist file. neat!

But I crash when calling setDelegate. I marked the methods final 
in NSApplication's definition as it was the only thing I found 
passing the compiler. Without it I get the missing implementation 
errors. I tried to new the interface and that didn't work either.

So I'm at a loss on how to declare this. I could split 
NSApplication into the interface to derive from and the one to 
call functions on, but that kind of breaks everything and I can't 
use one in all definitions and cast to the other in all 
implementations, that would be crazy :)
Jan 09 2016
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2016-01-09 11:09, Jeremie Pelletier wrote:
 Hello, I'm trying to see if I can write a full Cocoa app in D, and I'm
 having trouble creating D classes when the underlying Objective-C
 interfaces have methods.
D doesn't yet support implementing Objective-C methods or classes in D. It currently only supports binding to existing Objective-C classes and instance methods. If you need anything more than that you either need to wait until that is implemented or fall back to using the Objective-C runtime functions [1]. [1] https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/ -- /Jacob Carlborg
Jan 09 2016
prev sibling parent reply Guillaume Piolat <first.last gmail.com> writes:
On Saturday, 9 January 2016 at 10:09:12 UTC, Jeremie Pelletier 
wrote:
 Hello, I'm trying to see if I can write a full Cocoa app in D, 
 and I'm having trouble creating D classes when the underlying 
 Objective-C interfaces have methods.

 It works for the app delegate because it needs to override 
 them, but for other classes the compiler says the Objective-C 
 methods aren't implemented in the D subclass.
If you are looking to implement/override Obj-C methods in D, I have done it here deriving from NSView https://github.com/p0nce/dplug/blob/master/window/dplug/window/cocoawindow.d#L426 Using the Obj-C runtime, the D object declares a new class object, populates it with methods (inverse mapping is done with an instance variable containing "this"). Ugly, but works. Example of a method callback: https://github.com/p0nce/dplug/blob/master/window/dplug/window/cocoawindow.d#L499 Do not forget to prepend the callback arguments with id and selector.
Jan 10 2016
parent reply Jeremie Pelletier <jeremiep gmail.com> writes:
On Sunday, 10 January 2016 at 21:51:53 UTC, Guillaume Piolat 
wrote:
 On Saturday, 9 January 2016 at 10:09:12 UTC, Jeremie Pelletier 
 wrote:
 Hello, I'm trying to see if I can write a full Cocoa app in D, 
 and I'm having trouble creating D classes when the underlying 
 Objective-C interfaces have methods.

 It works for the app delegate because it needs to override 
 them, but for other classes the compiler says the Objective-C 
 methods aren't implemented in the D subclass.
If you are looking to implement/override Obj-C methods in D, I have done it here deriving from NSView https://github.com/p0nce/dplug/blob/master/window/dplug/window/cocoawindow.d#L426 Using the Obj-C runtime, the D object declares a new class object, populates it with methods (inverse mapping is done with an instance variable containing "this"). Ugly, but works. Example of a method callback: https://github.com/p0nce/dplug/blob/master/window/dplug/window/cocoawindow.d#L499 Do not forget to prepend the callback arguments with id and selector.
Sweet! I can at least get started while the full DIP gets implemented :) I already have the Metal bindings more or less ready to publish, I'll try to work on the Cocoa ones this weekend and see how much I can progress! Oh by the way, I see the DIP declares blocks with the __block keyword, shouldn't it be better to reuse delegate with extern(Objective-C) ? Feels cleaner and more consistent with the rest of the language to me.
Jan 17 2016
next sibling parent reply Jeremie Pelletier <jeremiep gmail.com> writes:
On Sunday, 17 January 2016 at 13:21:39 UTC, Jeremie Pelletier 
wrote:
 On Sunday, 10 January 2016 at 21:51:53 UTC, Guillaume Piolat 
 wrote:
 On Saturday, 9 January 2016 at 10:09:12 UTC, Jeremie Pelletier 
 wrote:
 Hello, I'm trying to see if I can write a full Cocoa app in 
 D, and I'm having trouble creating D classes when the 
 underlying Objective-C interfaces have methods.

 It works for the app delegate because it needs to override 
 them, but for other classes the compiler says the Objective-C 
 methods aren't implemented in the D subclass.
If you are looking to implement/override Obj-C methods in D, I have done it here deriving from NSView https://github.com/p0nce/dplug/blob/master/window/dplug/window/cocoawindow.d#L426 Using the Obj-C runtime, the D object declares a new class object, populates it with methods (inverse mapping is done with an instance variable containing "this"). Ugly, but works. Example of a method callback: https://github.com/p0nce/dplug/blob/master/window/dplug/window/cocoawindow.d#L499 Do not forget to prepend the callback arguments with id and selector.
Sweet! I can at least get started while the full DIP gets implemented :) I already have the Metal bindings more or less ready to publish, I'll try to work on the Cocoa ones this weekend and see how much I can progress! Oh by the way, I see the DIP declares blocks with the __block keyword, shouldn't it be better to reuse delegate with extern(Objective-C) ? Feels cleaner and more consistent with the rest of the language to me.
Turns out I can't execute most of my bindings yet :( I used interface inheritance all over the place to fully reproduce Cocoa and Metal, and while it does compile correctly, calling a objc method from an interface inherited through another interface causes a segmentation fault. For example: interface NSObjectProtocol { // dispose method here } interface NSString : NSObjectProtocol {} If I get an instance of NSString and call its dispose method, the process segfaults. If I lift the dispose method into NSString it works correctly. At this point I'll wait for more support, there's just too much to copy/paste :)
Jan 17 2016
parent Jacob Carlborg <doob me.com> writes:
On 2016-01-17 16:18, Jeremie Pelletier wrote:

 At this point I'll wait for more support, there's just too much to
 copy/paste :)
Perhaps a mixin could help with minimizing copy/paste. -- /Jacob Carlborg
Jan 18 2016
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2016-01-17 14:21, Jeremie Pelletier wrote:

 Oh by the way, I see the DIP declares blocks with the __block keyword,
 shouldn't it be better to reuse delegate with extern(Objective-C) ?
 Feels cleaner and more consistent with the rest of the language to me.
That part is not implemented yet. We'll see how it'll look like when/if it gets implemented :) -- /Jacob Carlborg
Jan 18 2016