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