Windows 7 64位并通过P / Invoke& amp ;;访问Win32 API调用元帅问题

时间:2011-08-23 21:46:51

标签: c# .net winapi usb pinvoke

我对.net / C#相对较新(虽然在Win32 / MFC和其他平台上非常有经验)并且需要编写一个实用程序来与自定义USB HID设备通信。该协议非常简单,我已经有了一个用MFC编写的工作实用程序,但是我更愿意在.Net / C#中编写该实用程序,因为我试图随着时间的推移而离开MFC。

我做了一些调查并发现了这篇文章,它似乎帮助我理解如何从.Net / C#访问HID设备,特别是因为它只是调用我已经熟悉的Win32 API调用:

http://www.developerfusion.com/article/84338/making-usb-c-friendly/

提供的示例代码给了我一个很好的介绍,如何访问Win32 API调用与USB设备通信(就像我以前的MFC代码一样),这一切都适用于32位安装的Windows Vista或7 ,但是当我尝试在64位安装上运行相同的代码时,它失败了。即使我尝试创建专用的64位应用程序,它仍然会失败。

我很确定问题是Marshal如何将参数(在堆栈上?)传递给Win32 API,但是我在这个阶段对.Net / C#的知识和经验还不够理解究竟是什么问题以及如何解决问题 - 这个问题可能比我目前所处的水平更为先进。

在我达到指令之前,代码中的所有内容似乎都能正常工作......

while (SetupDiEnumDeviceInterfaces(hInfoSet, 0, ref gHid, (uint)nIndex, ref oInterface))    // this gets the device interface information for a device at index 'nIndex' in the memory block

其中SetupDI ...在32位系统上返回true,然后遍历所有连接的USB设备,但在64位系统上返回false。我很确定这可能是参数如何传递到Win32 API函数的问题,但我不明白究竟是什么问题。该函数的DLLImport定义是:

[DllImport("setupapi.dll", SetLastError = true)] protected static extern bool SetupDiEnumDeviceInterfaces(IntPtr lpDeviceInfoSet, uint nDeviceInfoData, ref Guid gClass, uint nIndex, ref DeviceInterfaceData oInterfaceData);

我想知道是否有人能够建议违规参数可能是什么以及我如何修复它?

提前感谢您提供的任何帮助,如果需要更多信息,请提出要求! 富

2 个答案:

答案 0 :(得分:5)

来自MSDN

BOOL SetupDiEnumDeviceInterfaces(
  __in      HDEVINFO DeviceInfoSet,
  __in_opt  PSP_DEVINFO_DATA DeviceInfoData,
  __in      const GUID *InterfaceClassGuid,
  __in      DWORD MemberIndex,
  __out     PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
);
DeviceInfoData [in,optional]
指向SP_DEVINFO_DATA结构的指针......

请注意,DeviceInfoData是一个指针 - 所以应该是IntPtr,而不是uInt:

    [DllImport("setupapi.dll", SetLastError = true)] protected static
    extern bool SetupDiEnumDeviceInterfaces(IntPtr lpDeviceInfoSet,
        IntPtr pDeviceInfoData, ref Guid gClass,
        uint nIndex, ref DeviceInterfaceData oInterfaceData);

调用它时,传递IntPtr.Zero而不是0。

答案 1 :(得分:2)

您可以通过检查GetLastError中的值来跟踪有问题的参数问题(如果这就是它),这可以从.NET应用程序中的Marshal.GetLastWin32Error()获得。

一个可能的问题可能是oInterface变量的初始化方式。应该设置cbSize元素。该结构的64位版本(SP_DEVICE_INTERFACE_DATA)可能比32位版本大。我刚才简单地看了一眼,脑子里想着(总是容易出错),看起来32位版本是28字节,64位版本是32字节。