2012-11-27 176 views
2

我一直在尝试连接到GPS接口卡的设备驱动程序。我从供应商那里得到的例子是C++。我试图得到它使用C#中工作的PInvoke获取设备句柄时出错

class HaveQuick 
{ 
    [DllImport("setupapi.dll", CharSet = CharSet.Auto)] 
    static extern IntPtr SetupDiGetClassDevs(
     ref Guid ClassGuid, 
     IntPtr Enumerator, 
     IntPtr hwndParent, 
     uint Flags 
     ); 

    [DllImport(@"setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    public static extern Boolean SetupDiEnumDeviceInterfaces(
     IntPtr hDevInfo, 
     ref SP_DEVINFO_DATA devInfo, 
     ref Guid interfaceClassGuid, 
     UInt32 memberIndex, 
     ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData 
    ); 

     Guid GUID_DEVINTERFACE_IPHQT = new Guid(0x13ff045f, 0xe9d2, 0x479c, 0xb3, 0x90, 0x8c, 0xae, 0xc7, 0xd1, 0x1c, 0xc4); 
     hDeviceInfo = SetupDiGetClassDevs(ref GUID_DEVINTERFACE_IPHQT, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); 
     if (hDeviceInfo == IntPtr.Zero) 
     { 
      lastError = Marshal.GetLastWin32Error(); 
      Console.WriteLine("**Error: couldn't get class info error code = {0}\n"); 
      return; 
     } 

      // Find the interface for device 
     devNum = 0x0000;  
     SP_DEVICE_INTERFACE_DATA interfaceData = new SP_DEVICE_INTERFACE_DATA();    // Interface data for this device 
     interfaceData.cbSize = (uint)Marshal.SizeOf(interfaceData); 
     SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA(); 
     deviceInfoData.cbSize = (uint)Marshal.SizeOf(deviceInfoData); 
     success = SetupDiEnumDeviceInterfaces(hDeviceInfo, ref deviceInfoData, ref GUID_DEVINTERFACE_IPHQT, devNum, ref interfaceData); 
     if (!success) 
     { 
      lastError = Marshal.GetLastWin32Error(); 
      Console.WriteLine("**Error: couldn't enum device error number = {0}\n", lastError); 

}

当我运行代码,我得到lasterror = 87是无效的参数

如果我有这行代码 取代success = SetupDiEnumDeviceInterfaces(hDeviceInfo,IntPtr.Zero,ref GUID_DEVINTERFACE_IPHQT,devNum,ref interfaceData);

我得到lasterror = 1784 Invlid用户缓冲区。

感谢您的帮助

+0

如果您需要无效用户缓冲区错误的帮助,您可能应该发布一个新问题。包含函数的C++原型,以及您正在使用的结构的C++和C#版本。 –

回答

0

SetupDiGetClassDevs原型没有SetLastError=true。因此拨打Marshal.GetLastWin32Error可能无法获得正确的值。此外,除非通话返回值无效,否则不应检查最后一个错误。

由于文档GetLastError说:

你应该立即拨打GetLastError函数时 函数的返回值表示,这样的调用将返回有用 数据。

所以图案使用Marshal.GetLastWin32Error应该是:

IntPtr hDeviceInfo = SetupDiGetClassDevs(...); 
if (hDeviceInfo == IntPtr.Zero) 
{ 
    // error here 
    lastError = Marshal.GetLastWin32Error(); 
} 

如果检查的最后一个错误时没有错误,也没有说什么样的价值,你会得到。并非所有函数在成功时都调用SetLastError,值为0。所以你可能会从很久以前得到一个错误。

+0

谢谢@Jim Mischel就是这样。所以我的问题是,当我得到设备接口 –

+0

顺便说一句,'IntPtr.Zero'可能不是检查的值。一些函数使用'-1'作为无效句柄值(因为在某些情况下0可以是有效的句柄)。 –