I want to call the following function from my managed code:
short LS_LoadConfig(LS_ID SensorID,LPVARIANT varConfigPathFile,BOOL bInit)
Here is how I declare the extern function in my C# class:
[DllImport("LineSensor.dll", EntryPoint = "#16")]
private static extern Int16 LS_LoadConfig(
Int16 deviceId,
IntPtr variantFilePath,
int init);
And here is how I create the VARIANT instance and I obtain a pointer to it. Then I call the C# function:
string filepath = @"C:\Windows\ ...";
IntPtr variantFilePath = Marshal.AllocCoTaskMem(200);
Marshal.GetNativeVariantForObject(filepath, variantFilePath);
LS_LoadConfig(device.Id, variantFilePath, initLineSensor);
The problem is that I keep receiving error messages such as "calling the LS_LoadConfig function has unbalanced the stack, check that parameters match the unmanaged signature".
It seems that the problem is caused by the second argument "variantFilePath", like it is not properly marshaled and its size on the unmanaged heap doesn't correspond to the one of an address (32-bit in my case). I tried to change the type in the C# function signature from IntPtr to int as follows:
[DllImport("LineSensor.dll", 开发者_Go百科EntryPoint = "#16")]
private static extern Int16 LS_LoadConfig(
Int16 deviceId,
int variantFilePath,
int init);
I tried to call the function passing a random number and it got slightly better, I have just received an error "memory access violation". Obviously because the random number wasn't a valid address.
Does anybody knows the solution to this problem?
Thank you for any helpful information.
The access violation you created is not better. It also prevents the MDA warning from being generated. Short from the argument types being wrong, the int16 looks pretty weird, the most likely trouble is caused by the CallingConvention. Try StdCall.
And declare the 2nd argument as "object", its default marshaling is to a VARIANT. Declare it with the "ref" keyword to get an LPVARIANT.
"calling the LS_LoadConfig function has unbalanced the stack, check that parameters match the unmanaged signature".
This usually means that you're using conflicting calling conventions between your native and managed code. C# by default uses stdcall, and c/c++ uses cdecl. Try specifying CallingConvention = CallingConvention.Cdecl.
精彩评论