Как использовать Windows DLL (с ​​поздним связыванием) методы в C ++? - PullRequest
1 голос
/ 29 сентября 2011

В основном я пытался заставить это работать в течение последних нескольких дней, но все мои попытки и все примеры / предложения, найденные в сети, потерпели неудачу. Я пытаюсь использовать методы Microsoft "setupapi.dll" при реализации моих собственных .dll для доступа к периферийному устройству, которое я создал.

Прямо сейчас я просто пытаюсь использовать метод «SetupDiGetClassDevs» из «setupapi.dll» для получения списка подключенных HID-устройств на моем компьютере. Я перепробовал все, начиная с «AfxLoadLibrary» и заканчивая «__declspec (dllimport)», и почти все остальное, что нашел в Интернете, но безрезультатно.

Я нашел рабочие примеры в C #, но не нашел ничего, что компилируется даже в C ++. Я использую Microsoft Visual C ++ 2010 Express в 64-разрядной версии Windows 7, если это имеет значение (в идеале я хотел бы, чтобы она была независимой от ОС - по крайней мере, в более поздних версиях 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 не идеальна. поэтому я хотел бы знать, что необходимо для его реализации (файлы заголовков и т. д.) или есть ли другой лучший способ сделать это. по-видимому, есть также некоторые проблемы, которые могут возникнуть при использовании «loadlibrary» в DLL (особенно в точке входа DLLMain), но, учитывая мой недостаток опыта в использовании .dll, я не совсем уверен, что они есть.

1 Ответ

3 голосов
/ 29 сентября 2011

Ваш код не работает, потому что вы передаете неправильное имя функции 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"));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...