Bug 33709 - Exposing managed type as protocol to native code
Summary: Exposing managed type as protocol to native code
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: unspecified
Hardware: PC Mac OS
: --- enhancement
Target Milestone: (C7)
Assignee: Rolf Bjarne Kvinge [MSFT]
Depends on:
Reported: 2015-09-04 18:43 UTC by Cody Beyer (MSFT)
Modified: 2016-01-22 17:06 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Cody Beyer (MSFT) 2015-09-04 18:43:57 UTC
### Description

Exposing a managed type as a protocol causes Failed to marshal the Objective-C object

For forum post: https://forums.xamarin.com/discussion/49233/exposing-managed-type-as-protocol-to-native

### Code

>    [Protocol(Name = "Test")]
>    public interface Test
>    {
>       [Export("print")]
>       void Print();
>    }

### Error

>Failed to marshal the Objective-C object 0x7f81c24230e0 (type: Protocol). Could not find an existing managed instance for this >object, nor was it possible to create a new managed instance (because the type 'ObjCRuntime.Protocol' does not have a >constructor that takes two (IntPtr, bool) arguments).

### Workaround

Pass an IntPtr in the constructor

>void SomeMethod(IntPtr protocol)
>   Protocol p = new Protocol(protocol);
>   Console.Writeline("Got {0}", p.Name);
Comment 1 Fraser Ruffelll 2015-09-04 19:15:56 UTC
For a bit of clarification the problem is with calling a bound managed method with an argument of type Protocol from native code:

>void SomeMethod(Protocol protocol)
>   Console.Writeline("Got {0}", p.Name);

Calling this method from the native side:

[someClass someMethod:@protocol(NSObject)]

will result in the reported exception above regardless of the protocol type. 

Changing the method signature to an IntPtr and then manually instantiating the Protocol is the current workaround:

>void SomeMethod(IntPtr protocol)
    Protocol p = new Protocol(protocol);
>   Console.Writeline("Got {0}", p.Name);
Comment 2 Rolf Bjarne Kvinge [MSFT] 2016-01-22 17:06:28 UTC

maccore/master: a62bc85a638eee7dbfe31dd8b222931150e4e75b