[Mono-dev] Embedded API: delegate type building

Robert Jordan robertj at gmx.net
Fri Mar 4 17:16:20 UTC 2016

Hi Jonathan,

You may want to have a look at this repo:


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.


Implement an icall with the following signature:

UniversalDelegateServices_NativeHandler(void *context,
   MonoArray *params)

Register it with:

mono_add_internal_call (

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

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

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

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.


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
> {
> 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
> 		extern static string FilePathCallback(string EmployerName);
> #endif
> 		public CloudClient(Func<string, string> filePathCallback) {
> 			_filePathCallback = filePathCallback;
> 			if (_filePathCallback == null) {
> 				_filePathCallback = FilePathCallback;
> 			}
> #endif
> 		}
> }
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list

More information about the Mono-devel-list mailing list