I think I have basically understood how to write c# delegates for callbacks, but this one is confusing me. The c++ definition is as follows:
typedef int (__s
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
unsafe delegate int CallbackDelegate (int lCode, int lParamSize, IntPtr pParam);
If .NET assumes cdecl instead of stdcall, your stack will most assuredly be hosed.
A .NET long
is 64bits. A C++ long
may be just 32bits. Check with the C++ compiler which compiled that definition as to what size it's long
s are.
I added your code to my current project where I'm doing a lot of C#/C++ interop in VS2012. And while I hate to use the "it worked on my machine", it worked fine for me. The code as I ran it is listed out below just to illustrate that I didn't make and fundamental changes.
My suggestion is that you build a new native dll with a stub function for _Initialize such as below and see if it works when you can control both sides of the interface. If that works but the real dll doesn't, it comes down to either compiler settings on the native side or their is a bug on the native side and it is stomping on the stack.
extern "C" {
typedef int (__stdcall* Callback)(long lCode,long lParamSize,void* pParam );
TRADITIONALDLL_API int __stdcall _Initialize (const char* FileName,Callback cbFunction, int Code,
const char* Name,unsigned int Option,unsigned int Option2)
{
cbFunction(0, 0, nullptr);
return 0;
}
}
On the C# side, I added the declarations to my interface class:
public delegate int CallbackDelegate(int lCode, int lParamSize, IntPtr pParam);
[DllImport("XXX.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int _Initialize(string FileName, CallbackDelegate cbFunction, int Code, string Name, uint Options, uint Options2);
And then in my main:
private int onCallback(int lCode, int lParamSize, IntPtr pParam)
{
return 0;
}
XXXInterface.CallbackDelegate del = new XXXInterface.CallbackDelegate(onCallback);
Console.Write(XXXInterface._Initialize("SomeFile.dat", del, 1000, "", 0, 4));