我有一个(C / C ++)DLL,我通过DLLImport调用C#项目。 这个DLL有这个方法:
int __stdcall Connect(OUT int *p_sessionID, IN BYTE mode, IN BYTE comport, IN char *servername, IN DWORD serverport);
我尝试了几种方式来翻译"它到C#,但我发现更接近的是:
[DllImport("UnmanagedDLL.dll", EntryPoint = "Connect", CallingConvention = CallingConvention.StdCall)]
private static extern unsafe int CS1_Connect(out IntPtr p_sessionID, byte mode, byte comport, string servername, int serverport);
我试图像这样调用:
IntPtr connection;
var i = Connect(out connection, 1, 0, "192.0.0.1", 1982);
但我总是收到以下错误:
附加信息:调用PInvoke函数' DllImportTest!DllImportTest.Program :: Connect'堆栈不平衡。这很可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。
我知道我可以访问DLL,因为我有另一种方法可以正常工作。
我做错了什么?
感谢。
答案 0 :(得分:0)
您的第一个参数翻译错误。
OUT int *p_sessionID
这里OUT
是一个宏,表示读者的语义。宏将它扩展为空。所以在预处理之后你就有了:
int *p_sessionID
翻译为
out int sessionID
在您的C#中。
您不需要将该函数声明为不安全,请删除它。最后一个参数是无符号的。您可能希望切换到uint
。
因此,正确的翻译是:
[DllImport("UnmanagedDLL.dll", EntryPoint = "Connect",
CallingConvention = CallingConvention.StdCall)]
private static extern int CS1_Connect(
out int sessionID,
byte mode,
byte comport,
string servername,
uint serverport
);
如果您仍然收到堆栈不平衡消息,那么您将知道非托管函数没有您在问题中引用的签名。