C ++ DLL Функция Экспорт. DLL не остается загруженной - PullRequest
0 голосов
/ 25 мая 2011

привет, у меня следующая проблема, и я не могу понять, что происходит.

код DLL mylib.cpp (mylib.dll):

#include <Windows.h>
#include <tchar.h>

__declspec(dllexport) LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) {
    return CallNextHookEx(NULL, nCode, wParam, lParam);
    }

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserverd){

// Perform actions based on the reason for calling.
switch( fdwReason ) 
{ 
    case DLL_PROCESS_ATTACH:
     // Initialize once for each new process.
     // Return FALSE to fail DLL load.
        MessageBox(NULL,
        _T("DLL Loaded"),
        _T("DLL Loaded"),
        NULL);
        break;

    case DLL_THREAD_ATTACH:
     // Do thread-specific initialization.
        MessageBox(NULL,
        _T("DLL Unloaded"),
        _T("DLL Unloaded"),
        NULL);
        break;
    }
    return TRUE;
}

Код программы my_prog.cpp:

#include <Windows.h>
#include <tchar.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){

    FARPROC pHookProc;
    static HINSTANCE hInstDLL;

    hInstDLL = LoadLibrary(_T("mylib.dll"));
    pHookProc = GetProcAddress(hInstDLL, "HookProc");
    if (!pHookProc) {
        MessageBox(NULL,
            _T("GetProcAddress failed"),
            _T("GetProcAddress failed"),
            NULL);
    }
    return 0;
}

Оба файла компилируются без ошибок. Всякий раз, когда я запускаю my_prog.exe, он выдает сообщение «DLL Loaded», затем сразу же выдает сообщение «DLL unloaded», и в результате происходит GetProcAddress (). Может ли кто-нибудь пролить немного света на меня, пожалуйста. Почему он мгновенно выгружает DLL?

Спасибо всем заранее.

РЕДАКТИРОВАНИЕ:

Я заменил DLL_THREAD_ATTACH на DLL_PROCESS_DETACH, как предложено c-smile . Я проверяю и выполняю экспорт как: long __stdcall HookProc (int, unsigned int, long) (1) (0x00001000). GetProcAddress () по-прежнему не работает. Я получаю "DLL Loaded", GetProcAddress () не удалось, "DLL Unloaded"

Ответы [ 4 ]

2 голосов
/ 25 мая 2011
  1. Заменить DLL_THREAD_ATTACH на DLL_PROCESS_DETACH
  2. Убедитесь, что ваша функция экспортируется точно как "HookProc".
  3. Если не использовать файл .def для определения имени экспортафункция.
1 голос
/ 25 мая 2011

Две вещи:

  1. Не думайте, что DLL_THREAD_ATTACH означает, что что-то идет не так.Это то, что должно произойти, когда что-то ссылается на вашу DLL , как сказал c-smile .
  2. Поскольку это модуль компиляции C ++, ваш экспорт будет иметьискаженное имя ?HookProc@@YGJHIJ@Z - вот почему GetProcAddress(hInstDLL, "HookProc") терпит неудачу - это неправильное имя.

    Используйте

    extern "C"  __declspec(dllexport) LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);
    

    И вы получите более управляемое имя _HookProc@12,так что GetProcAddress(hInstDLL, "_HookProc@12") должно работать.

Если вы хотите еще более приятное имя, я думаю, вам нужно использовать файл DEF, начиная с http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx:

dllexport функции C ++ предоставит функцию с искажением имени C ++.Если искажение имени в C ++ нежелательно, либо используйте файл .def (ключевое слово EXPORTS), либо объявите функцию как extern "C".

Файл .def, подобный следующему, должен помочь (заметьте, что: ключевое слово EXPORTS чувствительно к регистру):

EXPORTS
    HookProc=_HookProc@12

Передайте файл .def компоновщику, используя параметр /def:whatever.def.

0 голосов
/ 25 мая 2011

В коде DLL при использовании DLL_PROCESS_DETACH:

"Параметр lpReserved указывает, выгружается ли DLL в результате вызова FreeLibrary, сбоя загрузки или завершения процесса."

Так что я бы проверил этот параметр, это могло бы помочь сузить проблему.

Я бы также проверял возвращаемое значение LoadLibrary, чтобы убедиться, что фактическая загрузка прошла успешно. Если LoadLibrary не работает, вы можете попробовать использовать API GetLastError () для получения дополнительной информации.

Также вы не делаете 'FreeLibrary (hInst);' после вашей LoadLibrary.

0 голосов
/ 25 мая 2011

Вместо MessageBox, вы можете попробовать printf? MessageBox является модальным и, вероятно, все портит.

...