使用 out 修饰符从非托管代码传递指针
Passing pointers from unmanaged code with out modifier
我有一个 (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);
我尝试了几种方法 "translate" 它到 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,因为我有另一种工作正常的方法。
我做错了什么?
谢谢。
您的第一个参数翻译不正确。
OUT int *p_sessionID
这里OUT
是一个宏,表示reader的语义。宏将其扩展为空。所以在预处理之后你有:
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
);
如果您仍然收到堆栈不平衡消息,那么您就会知道非托管函数没有您在问题中引用的签名。
我有一个 (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);
我尝试了几种方法 "translate" 它到 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,因为我有另一种工作正常的方法。
我做错了什么?
谢谢。
您的第一个参数翻译不正确。
OUT int *p_sessionID
这里OUT
是一个宏,表示reader的语义。宏将其扩展为空。所以在预处理之后你有:
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
);
如果您仍然收到堆栈不平衡消息,那么您就会知道非托管函数没有您在问题中引用的签名。