【发布时间】:2018-07-06 11:13:16
【问题描述】:
我有一个 c++ 头文件中的以下函数:
__int16 __stdcall s_em4305_login (HANDLE m_hUSB, int DataRate, UCHAR * password);
当我运行 VB 等价物时:
Private Declare Function RF_EM4305_Login Lib "SRF32.dll" Alias "s_em4305_login" (ByVal handle As Long, ByVal DataRate As Long, ByRef bytes As Byte) As Integer
我将 -1100 作为值返回
当我运行 c# 等效项时:
[DllImport("SRF32.dll", EntryPoint = "s_em4305_login")]
private static extern ushort RF_EM4305_Login(IntPtr handle, int DataRate,byte[] password);
我得到了不同的价值。第三个参数很可能被错误地声明了。有人可以协助将 c++ 声明转换为 c#
更新
我添加了一些额外的声明
private static extern ushort RF_EM4305_Login(IntPtr 句柄, int DataRate,IntPtr 密码);
private static extern ushort RF_EM4305_Login(IntPtr handle, int DataRate,ref byte[] password);
通过所有 3 个 c# 声明,我得到返回值“64436”。
【问题讨论】:
-
返回类型应该是
System.Int16akaShort。Integer在经典 VB 中是 16 位的,但在 VB.NET 中不是。同样,第二个参数应该是System.Int32akaInteger。Long在经典 VB 中是 32 位,但在 VB.NET 中也发生了变化。而且第一个参数有问题,应该像C#声明一样使用System.IntPtr。 VB.NET 和 C# 之间的不同结果并不意味着您的 C# 声明是错误的......相反,它似乎 C# 声明是正确的,而 VB.NET 调用是错误的。 -
作为一般建议,永远不要在 p/invoke 声明中对类型使用语言关键字。相反,请使用
System命名空间中的类型名称,明确描述大小。 -
@jwdonahue:可能
string和CharSet.Ansi一起使用会更容易,但byte[]并没有错。 -
在 C# 中尝试使用
System.Int16(或short)而不是ushort作为返回类型。我以为您的意思是返回值实际上是不同的,而不仅仅是处理无符号的相同位模式... -
@felix-b:所有为 Windows 平台制作的可以运行 C# 代码的 C++ 编译器都使用 32 位
int和 32 位long。