Is it possible to expose my own methods to C# in a custom native CoreCLR host environment?

471 views Asked by At

I've been following this guide to create my own .NET Core 6 host from an unmanaged C++ application using hostfxr.h and nethost.h, and interface with a managed DLL written in C#. I can retrieve and call C# methods marked with [UnmanagedCallersOnly] on the C++ side, but now I would like to do the opposite, and expose unmanaged C++ functions to the managed DLL. I've seen libraries like System.Math and the Unity engine use a very elegant solution where they declare methods as extern, and mark them with the [MethodImpl(InternalCall)] attribute, and provide the method body in native code. Examples:

[MethodImpl(MethodImplOptions.InternalCall)]
public static extern double Pow(double x, double y); // System.Math

[MethodImpl(MethodImplOptions.InternalCall)]
private extern void set_position_Injected(ref Vector3 value); // Unity Transform class

According to this page, the names of these methods must be registered as QCall/FCall/ECall on the unmanaged side, along with the native implementation. However I haven't been able to find any examples or guides on how this can be achieved. It must be possible somehow, because otherwise that guide wouldn't exist on the official dotnet github, I just can't figure out how to do it.

Just out of curiosity, I tried to define and call an extern method in my DLL with the InternalCall attribute and a random name, just to see what error it would throw, and this is what I got:

System.Security.SecurityException: ECall methods must be packaged into a system module.

Unfortunately this wasn't really helpful, as all it did was introduce a third _Call name, and made this already confusing topic even more confusing.

Is this even possible, and if it is, how can I access the necessary FCClassElement/FCFuncStart/FCFuncEnd/etc... macros to start exposing my own native methods to a managed C# DLL?

I would like to avoid COM, because as far as I know it's only available on Windows, and I'm trying to create a cross-platform solution.

0

There are 0 answers