Hi Jonathan,

You may want to have a look at this repo:

https://github.com/robert-j/Mono.Embedding/tree/master/Mono.Embedding

especially at UniversalDelegateServices.

UniversalDelegateServices is able to wrap (almost) all delegate
types with a UniversalDelegate with the following signature:

public delegate object UniversalDelegate(object[] args);

This basically means that you can handle all kind of delegate types
with only one internal call.


Recipe:


Implement an icall with the following signature:


MonoObject*
UniversalDelegateServices_NativeHandler(void *context,
  MonoArray *params)
{
  ...
}


Register it with:

mono_add_internal_call (
  name,
  &UniversalDelegateServices_NativeHandle);

"name" can be obtained by invoking
UniversalDelegateServices.GetInternalCallName ().


Whenever you need to create a delegate of a given type,
invoke

UniversalDelegateServices.CreateWrapper(type, context);

"context" is a user-defined IntPtr that will be passed
to your icall as the first argument. It can be an
instance ("this" ptr) of a native object, etc.

It's up to you how to handle "context" in the aforementioned
icall.

You could define a native base class "UniversalDelegate"
with a virtual "Handler" method with a signature
more friendly to your framework than
MonoObject*(void *, MonoArray*), etc.


Robert

On 04.03.2016 14:44, Jonathan Mitchell wrote:
Hi

At present I use an InternalCalls for my callbacks and conditional compilation 
(see end) in our cross platform code
In this we assign  a Func<string, string> directly to an extern static string 
FilePathCallback(string EmployerName);

  In future I would like to support calling methods such as

public CloudClient(Func<string, string> filePathCallback)

using the Embedded API and cut out the extra plumbing need for InternalCalls.

I have a wooly feel for how I should approach this!
When generating generic types I use a managed helper method.

So I could envisage creating a System.Delegate instance of System.Func<string, 
string>.
Then I could set the Target and Method properties - however since I am calling 
back into C there won’t be a Target class.
However System.Delegate is abstract so I would need to sort that out too! - 
presumably this needs to be done dynamically at runtime.

I am aware of the existence of Delegate.CreateDelegate() put that only seems to 
work for instance delegates.

Any insight would be helpful.

Thanks

Jonathan

end
===
public class CloudClient
{
#if TARGET_OSX
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                extern static string FilePathCallback(string EmployerName);
#endif
                public CloudClient(Func<string, string> filePathCallback) {

                        _filePathCallback = filePathCallback;

#if TARGET_OSX
                        if (_filePathCallback == null) {
                                _filePathCallback = FilePathCallback;
                        }
#endif
                }

}





_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list



_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to