I’ll add the ability to interact with C ++ code with .Net Core. In .Net Core it is possible to call static .Net methods through the use of coreclr.dll from native. View examples and links here. Cross-platform use of .Net classes from unmanaged code. Or analogue IDispatch on Linux
As a result, you can pass native methods to managed code and vice versa. But I was interested in using objects and virtual methods. Therefore, I asked a question and got an answer .Net Core Calling virtual methods of native objects At the same time, the method call goes to a bunch of QueryInterface, AddRef and Release.
I will give my example.
We describe the class in C ++
struct ICallback : IUnknown { public: // Унаследовано через IUnknown virtual HRESULT __stdcall QueryInterface(REFIID riid, void ** ppvObject) override; virtual ULONG __stdcall AddRef(void) override; virtual ULONG __stdcall Release(void) override; virtual HRESULT __stdcall execute(int value); }; typedef void(STDMETHODCALLTYPE *ManagedRunCallback)(ICallback*);
implementation
// {FFB46654-083E-486A-94B8-E28B5C01561D} static const GUID IID_ICallback = { 0xffb46654, 0x83e, 0x486a,{ 0x94, 0xb8, 0xe2, 0x8b, 0x5c, 0x1, 0x56, 0x1d } }; HRESULT __stdcall ICallback::execute(int value) { wprintf_s(L"ICallback from.Net %d\n", value); return NOERROR; } HRESULT __stdcall ICallback::QueryInterface(REFIID riid, void ** ppvObject) { if (!ppvObject) return E_INVALIDARG; if (riid == IID_IUnknown) { *ppvObject = static_cast<IUnknown*>(this); return S_OK; } else if (riid == IID_ICallback) { *ppvObject = static_cast<ICallback*>(this); return S_OK; } *ppvObject = nullptr; return E_NOINTERFACE; } // Меня интересует только вызов виртуальных методов // без отслеживания подсчета ссылок ULONG __stdcall ICallback::AddRef(void) { return 1; } ULONG __stdcall ICallback::Release(void) { return 0; }
now the description in C #
[ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("FFB46654-083E-486A-94B8-E28B5C01561D")] public interface ICallback { void execute(int value); }
and static method
public static void CallInterface(IntPtr cb) { var cb2 = Marshal.GetObjectForIUnknown(cb) as ICallback; cb2?.execute(555); }
I can now call the .Net method from C ++
ManagedRunCallback pRunCallback; if (!CreateDelegate(domainId, L"CallInterface", (INT_PTR*)&pRunCallback)) return false; ICallback* cb = new ICallback(); pRunCallback(cb);