Reputation: 22916
In Mono you can pass a delegate from C# to a C++ function which takes in the delegate as a function pointer. Can this be done in C# on Windows for example where you can compile a native C++ unmanaged library, link it against a C# project and get a C++ function to invoke a C# function via a function pointer which C# passed to it as a delegate?
Upvotes: 1
Views: 5625
Reputation: 1038
Rohit's answer is right, but there are lots more gotcha's on the path depending on whether you're calling back immediately (C# calls C++ which calls back C#) or if you want to call back repeatedly (C# calls C++ and after returning calls back one or more times later to C#).
i wrote this example from the perspective of Unity/C# and C/C++/Objective-C interop, but you may find some of the comments and code-snippets useful no matter where you are doing C#/C interop.
in particular make sure that you're propertly retaining/holding any delegates you pass from C#/managed to C/unmanaged code if the C/unmanaged code might be calling back at a different time.
Upvotes: 1
Reputation: 612794
You are looking for Marshal.GetFunctionPointerForDelegate()
.
Upvotes: 1
Reputation: 100527
This obviously can be done - all CLR hosts are native applications to start with. Your options:
Upvotes: 1
Reputation: 11787
Define a delegate in .NET, and then pass that to your unmanaged code. The CLR will expose the delegate as a function pointer which you can call from your unmanaged code.
The interop layer does not know how to handle references in C++. So You need to expose the object as a pointer, not a reference. Additionally, .NET doesn't know what a C++ object is (it's not the same as System.Object). That will need to be passed as an IntPtr, and I don't think there is much you can do with it in .NET.
C++ callbacks:
typedef void (*CBFUNC1)(unsigned int, const char*, object&);
typedef object* (*CBFUNC2)(object*, struct _mystruct* );
C# signatures for the delegates would be
delegate void CbFunc1(uint param1, [MarshalAs(UnmanagedType.LPStr)] string
param2, IntPtr param3);
delegate IntPtr CbFunc2(IntPtr param1, ref _mystruct param2);
Upvotes: 6
Reputation: 1959
One option you have is to use C++/CLI to call into the C# code. If your C++ code must stay unmanaged (native), then you should wrap your C# code in a COM component and use it from your C++ code.
Upvotes: 1