C++函数s_em4305_login转C# DLL导入声明求助
解决C++到C#的P/Invoke声明错误问题
让我们一步步排查并修正这个函数声明的问题,先从原C++函数的细节入手:
原C++函数声明:
__int16 __stdcall s_em4305_login (HANDLE m_hUSB, int DataRate, UCHAR * password);
核心问题分析
你遇到的返回值异常(64436)其实是第一个坑:返回值类型不匹配。C++的__int16是16位有符号整数,而你用了C#的ushort(无符号16位整数),负数-1100被强制转换成无符号后就变成了64436(计算方式:65536 - 1100 = 64436)。
第二个问题是第三个参数的 marshaling 方式错误,我们逐个参数对应梳理:
- 返回值:
__int16 __stdcall→ C#对应short(有符号16位整数),同时显式指定调用约定为StdCall(虽然是DllImport的默认值,但显式声明更清晰)。 - HANDLE m_hUSB:对应C#的
IntPtr,你之前的写法是正确的。 - int DataRate:C++的
int是32位有符号整数,对应C#的int,这部分没问题。 - UCHAR * password:这是指向无符号字节数组的指针,用于传递登录密码。你之前尝试的几种写法都有问题:
- 直接用
byte[]时,需要明确告诉CLR如何将其 marshaling 为非托管数组指针; ref byte[]会传递数组本身的引用(相当于C++的UCHAR**),完全不符合原函数的参数类型;IntPtr需要手动分配内存并拷贝数组,操作繁琐且容易出错。
- 直接用
正确的C#声明
[DllImport("SRF32.dll", EntryPoint = "s_em4305_login", CallingConvention = CallingConvention.StdCall)] private static extern short RF_EM4305_Login(IntPtr handle, int DataRate, [MarshalAs(UnmanagedType.LPArray)] byte[] password);
额外注意事项
- 确认
password数组的长度符合函数要求:EM4305模块的登录密码通常是4字节,所以你需要传递长度为4的byte[],如果长度不对也会导致调用失败。 - 确保
handle是有效的USB设备句柄,DataRate参数值符合模块支持的速率范围。
另外补充一下你VB声明的问题:ByRef bytes As Byte是传递单个字节的引用,而不是数组指针,这也是VB返回-1100错误码的原因。
内容的提问来源于stack exchange,提问作者Eminem
相关产品推荐
相关产品推荐

