I have an unmanaged C++ DLL and a .net application which communicate using P/Invoke . I need to update a dictionary within the .net app from a C++ DLL.
I tried to do that in the following way:
public delegate void MyDelegate(string address, string username);
[DllImport("MyDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void SaveMyDelegate(MyDelegate callback);
private static SortedDictionary<string, string> dict = new SortedDictionary<string, string>();
public void save_delegate() {
SaveMyDelegate(delegate(string address, string username) {
if (username != "") {
dict.Add(address, username);
}
});
}
On C++ side I have:
typedef void (*MANAGED_CALLBACK)(string user_address, string username);
extern "C" __declspec(dllexport) void SaveMyDelegate(MANAGED_CALLBACK callback);
MANAGED_CALLBACK my_callback;
void SaveMyDelegate(MANAGED_CALLBACK callback) {
my_callback = callback;
}
extern "C" __declspec(dllexport) VOID start_collection();
VOID start_collection() {
my_callback("test", "User");
}
On C# I do the following calls:
[DllImport("MyDLL.dll")]
public static extern void start_collection();
private void Button1_Click(object sender, EventArgs e) {
save_delegate();
start_collection();
}
When I call start_collection() I get an AccessViolation exception. I tried to declare the delegate in the following way:
public delegate void MyDelegate(
[MarshalAs(UnmanagedType.LPStr)]string address,
[MarshalAs(UnmanagedType.LPStr)]string username);
I have also added this statement:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void MyDelegate(...)
I've not looked at every detail of your code, but some commonly seen p/invoke issues just out immediately:
c_str()
method of std::string
.cdecl
and so you need to use the [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
attribute when declaring the delegate type in C#.