I know, that GC can move objects, so if you want to avoid this for some time, you use
GCHandle.Alloc(..., GCHandleType.Pinned)
I want to pass a C# function to C++ DLL, which will be called several times. I saw this answer about how to pass C# function to C++ DLL and my approach is:
C++:
#include <string>
typedef void(*MyFunction)(const char*);
void foo(MyFunction func) {
for (int i = 0; i < 1000; i++) {
std::string s = std::to_string(i);
func(s.c_str());
}
}
C#:
class Program {
delegate void MyFunction([MarshalAs(UnmanagedType.LPStr)] string s);
[DllImport(..., CallingConvention = CallingConvention.Cdecl)]
static extern foo(MyFunction function);
static void Baz(string s) {
Console.WriteLine(s);
}
private static MyFunction delegateInstance;
static void Main(string[] args) {
delegateInstance = Baz;
foo(delegateInstance);
}
}
This program works fine if built for x64, but silently dies if built for x86. I think GC moves my Baz
function at some point and C++ DLL is trying to call it.
If it is, how can I avoid this?
Edit
It looks like the delegate functions must be declared with UnmanagedFunctionPointer
to look like
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void MyFunction([MarshalAs(UnmanagedType.LPStr)] string s);
Now it works fine, but does anyone knows, why is it necessary and did work on x64?