开发者

How to use windows DLL (late bound) methods in C++?

I've basically been trying to get this working for the last couple of days, but all of my attempts and all the examples/suggestions found online have failed. I'm trying to use Microsoft's "setupapi.dll" methods in implementing my own .dll to access a peripheral device I have created.

Right now I'm simply trying to use the method "SetupDiGetClassDevs" found in "setupapi.dll" to retrieve a list of attached HID devices on my computer. I've tried everything from "AfxLoadLibrary" to "__declspec(dllimport)" and pretty much everything else I've found online to no avail.

I've found working examples in C# but have not found anything that even compiles in C++. I am running Microsoft visual C++ 2010 express on Windows 7 64-bit if that makes a difference (ideally I'd want it to be OS independent - at least across more recent versions of windows). Any code samples that can successfully import/use this method would be greatly appreciated. (Also don't forget to mention any configuration settings/resource files/etc as I need to figure out a holistic process to make this work.)

UPDATE!!!:

so i finally got my code to compile using a combination of suggestions from the responses given here + some more googling. my current code is as follows (and fyi the main issue here was that an "L" had to be prefixed to the .dll in quotes):

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);

unfortunately i wasn't able to get this working using the "safeloadlibrary" function remy mentioned. and my impression from other forums is that the standard "loadlibrary" function is non-ideal. so i'd like to know what is needed to implement it (header files, etc) or if there is another better way to do this. apparently there are also some issues that may arise using "loadlibrary" in a DLL (particularly in DLLMain entry point) but given my lack of experience using .dll's i'm not really sure what they 开发者_如何转开发are.


Your code fails because you are passing the wrong function name to GetProcAddress(). Like most API functions that have string parameters, SetupDiGetClassDevs() has separate Ansi and Unicode flavors available (SetupDiGetClassDevsA() and SetupDiGetClassDevsW(), respectively), and the API header files transparently hide this detail from you. So you need to adjust your string value according to which flavor you actually want to use, eg:

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); 
}

Here is a simply trick to make the mapping easier to work with if you have multiple functions to load dynamically:

#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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜