我正在尝试将短类型的参数传递给从DLL导入的C ++非托管函数。在我的C ++ DLL代码中,我有以下功能:
__declspec(dllexport)void ChangeIcon(char *executableFile, char *iconFile,
UINT16 imageCount)
{
// Some code, doesn't matter
}
在C#托管代码中,我使用以下代码导入此函数:
[DllImport("IconChanger.dll")]
static extern void ChangeIcon(string executableFile, string iconFile,
ushort imageCount);
然后我称之为:
ushort imageCount = 2;
ChangeIcon("filePath", "iconPath", imageCount);
应用程序执行函数就好了;但是,弹出带有以下文字的消息:
托管调试助手'PInvokeStackImbalance'检测到'foo.exe'中存在问题。 附加信息:调用PInvoke函数'bar.IconChanger :: ChangeIcon'使堆栈失衡。这很可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。
如果我没有传递最后一个参数,则消息不会弹出,所以它必须是由于传递短类型。我也试过过int,会出现相同的消息。
显然,我在传递这个数字参数时做错了。如何匹配两者之间的参数?
答案 0 :(得分:3)
确保调用约定匹配。如果未指定调用约定,则假定为StdCall
。但是对于C / C ++,标准调用约定是Cdecl
。所以要么在C ++函数上使用__stdcall
:
void __declspec(dllexport) __stdcall ChangeIcon(char *executableFile, char *iconFile,
UINT16 imageCount)
{
// Some code, doesn't matter
}
或在CallingConvention.Cdecl
上指定DllImport
:
[DllImport("IconChanger.dll", CallingConvention = CallingConvention.Cdecl)]
答案 1 :(得分:0)
因为您在C ++函数的参数中使用char *,所以我建议您以这种方式导入函数: [DllImport(“IconChanger.dll”,CallingConvention = CallingConvention.Cdecl)] static extern void ChangeIcon([MarshalAs(UnmanagedType.LPStr)string executableFile,[MarshalAs(UnmanagedType.LPStr)string iconFile,ushort imageCount);