[rfc] NativeObjectAttribute: The class attribute to generate INativeObjects classes
- Dominant language
- C#
- Stars
- 2.9k
- Forks
- 576
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 96
Description
### Description
Currently we do not provide a mechanism in the generator to generate bindings for [Core Foundation objects](https://developer.apple.com/documentation/corefoundation/cftyperef?language=objc) or objects like [VTSession](https://developer.apple.com/documentation/videotoolbox/vtsession).
The idea is to teach the generator how to create the boilerplate code for this kind of objects and be used in conjunction of [`[ExternizerAttribute]`](https://github.com/xamarin/xamarin-macios/issues/3452) to simplify the binding process for this kind of objects.
Introducing `[NativeObject]`:
```csharp
[AttributeUsage (AttributeTargets.Interface, AllowMultiple = false)]
public class NativeObjectAttribute : Attribute {
public Visibility OwnsCtorVisibility { get; set; } = Visibility.Internal;
public NativeObjectAttribute () { }
public NativeObjectAttribute (Visibility ownsCtorVisibility) => OwnsCtorVisibility = ownsCtorVisibility;
}
```
This would be used as follows:
```csharp
[NativeObject]
interface NFoo {
}
```
This will instruct the generator to create a `partial` subclass of the following new abstract class named `NativeObject` that would live inside `ObjCRuntime` namespace:
```csharp
public abstract class NativeObject : INativeObject, IDisposable {
IntPtr handle;
public IntPtr Handle {
get => handle;
protected set => InitializeHandle (value);
}
protected NativeObject (IntPtr handle, bool owns)
{
Handle = handle;
if (!owns)
DangerousRetain ();
}
~NativeObject ()
{
Dispose (false);
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
protected virtual void Dispose (bool disposing)
{
if (Handle != IntPtr.Zero) {
DangerousRelease ();
handle = IntPtr.Zero;
}
}
protected virtual void DangerousRetain () => CFObject.CFRetain (Handle);
protected virtual void DangerousRelease () => CFObject.CFRelease (Handle);
protected virtual void InitializeHandle (IntPtr handle)
{
if (Handle == IntPtr.Zero && Class.ThrowOnInitFailure) {
throw new Exception ($"Could not initialize an instance of the type '{GetType ().FullName}': handle is null.\n" +
"It is possible to ignore this condition by setting ObjCRuntime.Class.ThrowOnInitFailure to false.");
}
this.handle = handle;
}
}
```
The generated code would look like this:
```csharp
public partial class NFoo : NativeObject {
internal NFoo (IntPtr handle, bool owns) : base (handle, owns)
{
}
}
```
Most of the time these objects have factory methods, this is the reason why the `.ctor (IntPtr,bool)` is `internal` and can be implemented either manually or by using the [`[ExternizerAttribute]`](https://github.com/xamarin/xamarin-macios/issues/3452).
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.