2011-09-29 88 views
1

我在過去的幾天裏基本上一直試圖讓這個工作,但我所有的嘗試和所有在網上找到的例子/建議都失敗了。我試圖使用微軟的「setupapi.dll」方法來實現我自己的.dll來訪問我創建的外圍設備。如何在C++中使用windows DLL(後期綁定)方法?

現在,我只是想使用的方法「SetupDiGetClassDevs」中的「setupapi.dll」發現我的電腦上檢索連接HID設備的列表。我試過了從「AfxLoadLibrary」到「__declspec(dllimport)」的所有內容,以及我在網上找到的其他一切都無濟於事。

我發現工作在C#的例子,但沒有發現任何東西,即使是在編譯C++。我在Windows 7 64位上運行Microsoft Visual C++ 2010 express,如果這有所作爲(理想情況下,我希望它與操作系統無關 - 至少在更新版本的Windows中)。任何可以成功導入/使用此方法的代碼示例都將不勝感激。 (也不要忘記提及任何配置設置/資源文件在/ etc因爲我需要找出一個整體的過程,使這項工作。)

更新!!!:

,所以我終於得到了我的代碼使用這裏給出的回覆中的建議組合進行編譯+使用更多的Google搜索。我現在的代碼如下(並且這裏的主要問題是「L」必須以引號中的.dll作爲前綴):

GUID InterfaceClassGuid = {0x4d1e55b2,0xf16f,0x11cf,0x88,0xcb,0x00 ,0x11,0x11,0x00,0x00,0x30};

HDEVINFO hDevInfo = INVALID_HANDLE_VALUE; 
    PSP_DEVICE_INTERFACE_DATA InterfaceDataStructure = new SP_DEVICE_INTERFACE_DATA; 
    SP_DEVINFO_DATA DevInfoData; 

    DWORD InterfaceIndex = 0; 
    DWORD StatusLastError = 0; 
    DWORD dwRegType; 
    DWORD dwRegSize; 
    DWORD StructureSize = 0; 
    PBYTE PropertyValueBuffer; 
    bool MatchFound = false; 
    DWORD ErrorStatus; 
    BOOL BoolStatus = FALSE; 
    DWORD LoopCounter = 0; 

    HINSTANCE dllHandle = LoadLibrary(L"setupapi.dll"); 
    if(dllHandle) 
    { 
     typedef HDEVINFO (WINAPI *pFUNC)(LPGUID, PCTSTR, HWND, DWORD); 
     pFUNC SetupDiGetClassDevs = (pFUNC) GetProcAddress(dllHandle, 
      #ifdef UNICODE 
      "SetupDiGetClassDevsW" 
      #else 
      "SetupDiGetClassDevsA" 
      #endif 
     ); 
     if(SetupDiGetClassDevs) 
      hDevInfo = SetupDiGetClassDevsW(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); 

     FreeLibrary(dllHandle); 

遺憾的是我沒能得到使用中提到的「safeloadlibrary」功能雷米這個工作。而我對其他論壇的印象是,標準的「加載庫」功能並不理想。所以我想知道實現它需要什麼(頭文件等),或者如果有另一種更好的方法來做到這一點。顯然也有一些問題,可能會出現使用DLL中的「loadlibrary」(特別是在DLLMain入口點),但鑑於我缺乏使用.dll的經驗,我不確定他們是什麼。因爲你傳遞錯誤的函數名GetProcAddress()

+4

你得到什麼錯誤?什麼失敗? –

+0

是的,檢查錯誤。這裏不需要extern C。 –

+0

我使用下面的雷米的建議列出了當前的錯誤。 fyi - 我最近剛剛使用了霰彈槍的方法,試着看看它是否會有所作爲。 「extern c」這個事情就是這樣一個例子,但之後就被刪除了。使用方法 – Ben

回答

3

你的代碼失敗。像大多數具有字符串參數的API函數一樣,SetupDiGetClassDevs()具有單獨的Ansi和Unicode風格(分別爲SetupDiGetClassDevsA()SetupDiGetClassDevsW()),並且API頭文件透明地隱藏了您的詳細信息。所以,你需要調整您的字符串值,根據其味,你真的想使用,如:

HINSTANCE dllHandle = SafeLoadLibrary("setupapi.dll"); 
if (dllHandle) 
{ 
    typedef HDEVINFO WINAPI (*pFUNC)(LPGUID, PCTSTR, HWND, DWORD); 
    pFUNC SetupDiGetClassDevs = (pFUNC) GetProcAddress(dllHandle, 
     #ifdef UNICODE 
     "SetupDiGetClassDevsW" 
     #else 
     "SetupDiGetClassDevsA" 
     #endif 
     ); 

    if (SetupDiGetClassDevs) 
     hDevInfo = SetupDiGetClassDevs(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); 

    FreeLibrary(dllHandle); 
} 

下面是一個簡單的技巧,使映射更容易使用,如果你有多個功能動態加載的工作:

#if defined(UNICODE) 
#define _MAP_WINNAME_STR(n) n "W" 
#else 
#define _MAP_WINNAME_STR(n) n "A" 
#endif 

pFUNC SetupDiGetClassDevs = (pFUNC) GetProcAddress(dllHandle, _MAP_WINNAME_STR("SetupDiGetClassDevs")); 
+0

我嘗試,得到了以下錯誤:爲WINAPI - 「調用約定可不能跟一個嵌套的聲明符」,爲HDEVINFO = SetupDiGetClassDevs(InterfaceGuid ...... - 「這個聲明沒有存儲類或類型說明符」和用於FreeLibrary則 - 「這個聲明沒有存儲類或類型說明符) – Ben

+1

嘗試改變的typedef'的typedef HDEVINFO(WINAPI * pFUNC)(LPGUID,PCTSTR,HWND,DWORD);'與括號內的WINAPI – rodrigo

+0

。 'WINAPI'只是'__stdcall'的一個typedef。我在我的typedefs中使用'WINAPI'之外的papahesis,它工作正常。 –