I'm trying to pass parameter of short type to C++ unmanaged function imported from DLL. In my C++ DLL code I have a following function:
__declspec(dllexport)void ChangeIcon(char *executableFile, char *iconFile,
UINT16 imageCount)
{
// Some code, doesn't matter
}
In C# managed code I import this function with the following code:
[DllImport("IconChanger.dll")]
static extern void ChangeIcon(string executa开发者_高级运维bleFile, string iconFile,
ushort imageCount);
And then I call it:
ushort imageCount = 2;
ChangeIcon("filePath", "iconPath", imageCount);
The application executes the function just fine; however, the message with the following text pops out:
Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in 'foo.exe'. Additional Information: A call to PInvoke function 'bar.IconChanger::ChangeIcon' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
If I do not pass the last parameter, the message doesn't pop out, so it must be due to passing short type. I have tried with int too, the same message appears.
Obviously, I'm doing something wrong when passing this numerical parameter. How to match parameters between the two?
Make sure the calling convention matches. If you don't specify a calling convention StdCall
is assumed. However for C/C++ the standard calling convention is Cdecl
. So either use __stdcall
on your C++ function:
void __declspec(dllexport) __stdcall ChangeIcon(char *executableFile, char *iconFile,
UINT16 imageCount)
{
// Some code, doesn't matter
}
or specify CallingConvention.Cdecl
on the DllImport
:
[DllImport("IconChanger.dll", CallingConvention = CallingConvention.Cdecl)]
As a side note, UInt16 is not CLS a compliant type so you probably want Int16 if you need this compliance.
Because you are using char* in the parameters of the C++ functions I recommend you to import the function in this way: [DllImport("IconChanger.dll", CallingConvention = CallingConvention.Cdecl)] static extern void ChangeIcon([MarshalAs(UnmanagedType.LPStr)string executableFile, [MarshalAs(UnmanagedType.LPStr)string iconFile, ushort imageCount);
精彩评论