2012-11-27 170 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可以是有效的句柄)。 –