我有一个支持蓝牙HID的应用程序,我在其中一个调用上遇到异常:
托管调试助手' PInvokeStackImbalance'已在C:\ Users \ Joshua \ Documents \ Visual Studio 2012 \ Projects \ DS4 Tool \ DS4Windows \ bin \ Release \ DS4Windows.vshost.exe'中检测到问题。
附加信息:调用PInvoke函数' HidLibrary!HidLibrary.NativeMethods :: HidD_GetSerialNumberString'堆栈不平衡。这很可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。
C ++签名:
BOOLEAN __stdcall HidD_GetSerialNumberString(
_In_ HANDLE HidDeviceObject,
_Out_ PVOID Buffer,
_In_ ULONG BufferLength
);
我的签名:
[DllImport("hid.dll")]
static internal extern bool HidD_GetSerialNumberString(IntPtr HidDeviceObject, byte[] Buffer, ulong BufferLength);
我的用法:
byte[] buffer = new byte[126];
NativeMethods.HidD_GetSerialNumberString(safeReadHandle.DangerousGetHandle(), buffer, (ulong)buffer.Length);
string MACAddr = System.Text.Encoding.Unicode.GetString(buffer).Replace("\0", string.Empty).ToUpper();
MACAddr = String.Format("{0}{1}:{2}{3}:{4}{5}:{6}{7}:{8}{9}:{10}{11}",
MACAddr[0], MACAddr[1], MACAddr[2], MACAddr[3], MACAddr[4],
MACAddr[5], MACAddr[6], MACAddr[7], MACAddr[8],
MACAddr[9], MACAddr[10], MACAddr[11]);
serial = MACAddr;
奇怪的是,尽管有错误,该方法仍会返回MAC地址。我应该忽略它吗?有没有更好的方法来检索MAC?
答案 0 :(得分:3)
C函数的 BufferLength 参数的类型为ULONG
。 ULONG 是 32位数据类型(请参阅MSDN documentation)。另一方面,C#中的 ulong 是64位数据类型,因此与非托管/本机 ULONG 不匹配。
与非托管/本机 ULONG 数据类型对应的32位C#数据类型为uint
,因此函数的C#声明应如下所示:
[DllImport("hid.dll")]
static internal extern bool HidD_GetSerialNumberString(
IntPtr HidDeviceObject,
byte[] Buffer,
uint BufferLength
);
(供将来参考:MSDN文档提供了一个显示which C# data type should be used for which unmanaged/native data type的表。不幸的是,此表未涵盖WINAPI中使用的所有非托管/本机数据类型。)