Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3rd party bindings and CMSampleBuffer usage in trampolines #5692

Closed
dalexsoto opened this issue Mar 1, 2019 · 8 comments
Closed

3rd party bindings and CMSampleBuffer usage in trampolines #5692

dalexsoto opened this issue Mar 1, 2019 · 8 comments
Assignees
Labels
bug If an issue is a bug or a pull request a bug fix iOS Issues affecting iOS macOS Issues affecting macOS
Milestone

Comments

@dalexsoto
Copy link
Member

Description

We have a report that using CMSampleBuffer in delegates on 3rd party bindings throws the following error:

error CS1729: 'CMSampleBuffer' does not contain a constructor that takes 2 arguments

Binding code:

[BaseType (typeof (NSObject))]
interface Foo {
	[Export ("enumerateSampleBuffers:")]
	void Enumerate (Action<CMSampleBuffer, NSError> handler);
}

This happens because we are special casing CMSampleBuffer in our generator and we are manually calling the .ctor(IntPtr, bool):

https://github.com/xamarin/xamarin-macios/blob/507d37eef68f13aec954121a2d441702bf87864e/src/generator.cs#L1617-L1624

But the .ctor(IntPtr, bool) of CMSampleBuffer is internal so it cannot be used by 3rd party bindings this way:

https://github.com/xamarin/xamarin-macios/blob/507d37eef68f13aec954121a2d441702bf87864e/src/CoreMedia/CMSampleBuffer.cs#L67-L74

Posible Solutions

Solution 1

Make the generator use Runtime.GetINativeObject<T> (IntPtr, bool) but this adds some overhead other than simply using the .ctor(IntPtr, bool) and most scenarios where CMSampleBuffer is used require speed which leads into the next solution.

Solution 2

Turn the .ctor(IntPtr, bool) of CMSampleBuffer visibility public but this can lead to potential incorrect usage.

Solution 3

Make the generator aware of the 3rd party binding context and special case the the usage of Runtime.GetINativeObject<T> (IntPtr, bool) only for 3rd party bindings and keep the current behavior for our bindings.

Workaround

Bind the CMSampleBuffer as IntPtr:

[BaseType (typeof (NSObject))]
interface Foo {
	[Export ("enumerateSampleBuffers:")]
	void Enumerate (Action<IntPtr, NSError> handler);
}

Then in actual code usage code do:

foo.Enumerate ((sb, error) => {
	using (var sampleBuffer = Runtime.GetINativeObject<CMSampleBuffer> (sb, false)) {
		// Do something...
	}
});
@dalexsoto dalexsoto added bug If an issue is a bug or a pull request a bug fix macOS Issues affecting macOS iOS Issues affecting iOS labels Mar 1, 2019
@dalexsoto dalexsoto added this to the Future milestone Mar 1, 2019
@dalexsoto dalexsoto self-assigned this Mar 1, 2019
@dalexsoto
Copy link
Member Author

Myself I lean towards Solution 3.

@spouliot
Copy link
Contributor

spouliot commented Mar 1, 2019

I'd say solution #2 with Advanced (or maybe Never) for blocking IntelliSense from suggesting it when people write code. Maybe an [Advice] too ?

@dalexsoto
Copy link
Member Author

Oh I did not think about Advice + Never or Advanced yeah I think Option 2 makes more sense now.

@rolfbjarne
Copy link
Member

How does the generator handle all the other INativeObject subclasses? I think we should use the same pattern everywhere.

@dalexsoto
Copy link
Member Author

@rolfbjarne we have some special cases but others generally are called with GetINativeObject<T> (IntPtr, false). I guess we have CMSampleBuffer special cased because performance(?), the special casing in the generator predates all of us 😄, goes beyond the initial import of maccore.

Other than the reflection performance impact to get the .ctor(IntPtr, bool) I do not see why it can't be called using GetINativeObject<T> (IntPtr, false).

@rolfbjarne
Copy link
Member

I had a look, and this is annoying :/

The default case in the generator is to call the IntPtr constructor directly: https://github.com/xamarin/xamarin-macios/blob/de8276445642e8589382f9c2346036b1bd8f74f8/src/generator.cs#L1634-L1638

However, for CMSampleBuffer we started calling the owns overload here: https://github.com/xamarin/maccore/commit/1ac93b5ebceb4a8526ab7ddce9496b1c732e078f, so that the CMSampleBuffer is automatically retained.

Turns out that fix is wrong, the correct fix is to make the CMSampleBuffer IntPtr constructor follow our INativeObject pattern like this:

internal CMSampleBuffer (IntPtr handle)
	: this (handle, false)
{
}

and now the CMSampleBuffer special case in the generator can be removed (we'd also have to audit everybody that calls this constructor to make sure we don't start leaking CMSampleBuffers).

Now this doesn't solve the problem with third-party bindings, but for that case I think Solution 3 is the best, because I don't like making the IntPtr constructors public (there's a reason we made the IntPtr constructors protected for NSObject subclasses).

@spouliot
Copy link
Contributor

spouliot commented Mar 1, 2019

I don't mind #3. Ideally we would avoid the following 3 situations - but it disqualifies all options ;-)

@dalexsoto
Copy link
Member Author

Since we now have #5693 I'll go for Option 3 for now.

dalexsoto added a commit to dalexsoto/xamarin-macios that referenced this issue Mar 4, 2019
Fixes dotnet#5692

3rd party bindings cannot use the `.ctor(IntPtr, bool)` of
`CMSampleBuffer` because it is `private`, they must use
`Runtime.GetINativeObject<T> (IntPtr, bool)` instead.
dalexsoto added a commit that referenced this issue Mar 4, 2019
Fixes #5692

3rd party bindings cannot use the `.ctor(IntPtr, bool)` of
`CMSampleBuffer` because it is `private`, they must use
`Runtime.GetINativeObject<T> (IntPtr, bool)` instead.
@ghost ghost locked as resolved and limited conversation to collaborators May 3, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug If an issue is a bug or a pull request a bug fix iOS Issues affecting iOS macOS Issues affecting macOS
Projects
None yet
Development

No branches or pull requests

3 participants