如何在C ++中使用Windows DLL(后期绑定)方法?

时间:2011-09-29 16:43:32

标签: c++ windows visual-c++ dll

我基本上一直试图让这个工作在最近几天,但我的所有尝试和在线发现的所有示例/建议都失败了。我正在尝试使用Microsoft的“setupapi.dll”方法来实现我自己的.dll来访问我创建的外围设备。

现在,我只是尝试使用“setupapi.dll”中的“SetupDiGetClassDevs”方法来检索计算机上连接的HID设备列表。我尝试了从“AfxLoadLibrary”到“__declspec(dllimport)”的所有内容,以及我在网上找到的其他所有内容都无济于事。

我在C#中找到了工作示例,但是在C ++中找不到任何甚至编译的东西。我在Windows 7 64位上运行Microsoft Visual C ++ 2010 Express,如果这有所不同(理想情况下我希望它独立于操作系统 - 至少在更新版本的Windows中)。任何可以成功导入/使用此方法的代码示例都将非常感激。 (另外不要忘记提及任何配置设置/资源文件/等,因为我需要找出一个整体过程来使这项工作。)

UPDATE !!!:

所以我最终得到了我的代码,使用这里给出的回复中的一些建议进行编译+更多google搜索。我目前的代码如下(这里的主要问题是“L”必须以引号括起来。)

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”函数来完成这项工作。而我对其他论坛的印象是标准的“loadlibrary”功能并不理想。所以我想知道实现它需要什么(头文件等)或者是否有另一种更好的方法来实现它。显然,在DLL中使用“loadlibrary”可能会出现一些问题(特别是在DLLMain入口点),但鉴于我缺乏使用.dll的经验,我不确定它们是什么。

1 个答案:

答案 0 :(得分:3)

您的代码失败,因为您将错误的函数名称传递给GetProcAddress()。与大多数具有字符串参数的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"));