Почему GetProcAddress не работает? - PullRequest
5 голосов
/ 16 апреля 2011

Сначала я создаю простую dll с именем SimpleDll.dll, ее заголовочный файл:

// SimpleDll.h
#ifdef MYLIBAPI
#else
#define MYLIBAPI __declspec(dllimport)
#endif

MYLIBAPI int Add(int a. int b);

ее исходный код:

// SimpleDll.c
#include <windows.h>

#define MYLIBAPI __declspec(dllexport)
#include "SimpleDll.h"    

int Add(int a, int b)
{
    return a + b;
}

Затем я вызываю ее в другом проекте ион работает нормально:

// TestSimpleDll.c
#include "stdafx.h"
#include <windows.h>
#include "SimpleDll.h"

#pragma comment(lib, "SimpleDll.lib")

int _tmain(int argc, _TCHAR* argv[])
{
    printf("%d", Add(10, 30));    // Give the expected result 40
    return 0;
}

Однако, когда я звоню GetProcAddress, чтобы узнать его адрес, он не работает!

// TestSimpleDll2.c
#include "stdafx.h"
#include <windows.h>
#include "SimpleDll.h"

#pragma comment(lib, "SimpleDll.lib")

int _tmain(int argc, _TCHAR* argv[])
{
    printf("%d", Add(10, 30));    // Give the expected result 40
    HMODULE hModule = GetModuleHandleA("SimpleDll.dll");    // hModule is found
    PROC add_proc       = GetProcAddress(hModule, "Add");     // but Add is not found !
    //  add_proc is NULL!
    return 0;
}

Спасибо за вашу помощь.(PS: я использую VS2010 в Windows7)
Обновление:
Это то, что показывает обходчик зависимостей для файла SimpleDll.dll:

enter image description here

Ответы [ 2 ]

5 голосов
/ 16 апреля 2011

Вам следует использовать файл .def, если вы хотите экспортировать имя для GetProcAddress. В противном случае вам придется иметь дело с именем c ++ mangling и с символами.

Вы можете избежать искажения, объявив свою функцию как extern "C", но единственный способ избежать украшений - это использовать файл .DEF.

Еще одна вещь - в Обходчике зависимости - используйте F10 для переключения между украшенными и неокрашенными именами.

2 голосов
/ 16 апреля 2011

Dependency Walker является отличным инструментом для устранения проблем с DLL, например:

Я предполагаю, что вы компилируете DLL как C-код. В противном случае C ++ выполняет искажение имени, что может вызвать проблемы.

Чтобы избежать искажения имени, просто оберните определение экспорта в extern "C".

extern "C" {
    MYLIBAPI int Add(int a. int b);
}
...