dotnet / ClangSharp

Clang bindings for .NET written in C#
MIT License
907 stars 146 forks source link

Support generating bindings for Objective-C #254

Open john-h-k opened 3 years ago

john-h-k commented 3 years ago

Clang supports Objective-C and having the ability to generate code for it would be useful for many Apple-centric interop scenarios.

Work items

Support @protocols

Protocols are analogous to abstract classes/interfaces in C++/C#. They are a series of required methods and properties (getters and/or setters as in C#), and then optional methods and properties. Implementing types (called @interfaces) must implement required attributes, but not optional attributes, and a special method (respondsToSelector) is used to determine whether they are implemented. Due to this, publicly exposing all selectors is quite important.

Protocol methods are called via the magic-method objc_msgSend(), which you cast to the prototype of the method you wish to call, but prepend 2 implicit parameters (self of type `void, and_cmdof typeSEL).selfis thethispointer for instance methods, or the class pointer (retrieved viaobject_getClass("className")) for class (static) methods._cmdis the "selector" for the method, which is basically an opaque pointer handle that represents a method name (Obj-C does not support method overloading, but as parameter names are considered part of the method name, 2 methods with different parameter names are differently named, and this is reflected by the selector) and is used to identify the method you wish to call. Selectors are retrieved by callingsel_registerName("selector"), where the selector has the formatmethodName(for no params), ormethodName:param1:param2:param3` (you can remove param names but it can lead to ambiguities).

* there are actually a couple of different forms of objc_msgSend for different types of return value, but the principle is the same

Roughly how it would work for C# is:

@protocol MyObjcType <NSObject>

@required
- (void)hello;
- (int)add_two:(int)left, right:(int)right;

@end
struct MyObjType
{
    public static class Selectors
    {
        private static readonly SEL sel_hello = sel_registerName("hello");
        private static readonly SEL sel_add_two_left_right = sel_registerName("add_two:right:");
    }

    public void hello() => ((delegate* unmanaged <void*, SEL, void>)(delegate* unmanaged <void>)&objc_msgSend)(Unsafe.AsPointer(ref this), Selectors.sel_hello);
    public int add_two(int left, int right) => ((delegate* unmanaged <void*, SEL, int, int, int>)(delegate* unmanaged <void>)&objc_msgSend)(Unsafe.AsPointer(ref this), Selectors.sel_add_two_right, value);
}

Changes to clangsharp

Requires adding

CXString clangsharp_cursor_getSelector(/* expected: ObjCMethodDecl */ CXCursor C);
CXString clangsharp_cursor_getGetterName(/* expected: ObjCPropertyDecl */ CXCursor C);
CXString clangsharp_cursor_getSetterName(/* expected: ObjCPropertyDecl */ CXCursor C);
IsaacMarovitz commented 7 months ago

It's been several years since this issue was created, is there a possibility of this getting picked up? The lack of Objective-C support is blocking other projects like Silk.NET from binding to Apple APIs.

IsaacMarovitz commented 7 months ago

Perhaps a job for @Developer-Ecosystem-Engineering Ig not lol