Относительно GetProcAddress - PullRequest
0 голосов
/ 25 января 2012

У меня есть MyDll.dll и его функция определена как показано ниже

void pascal Myfunction(BOOL);

, когда я пытаюсь использовать функцию в другом проекте, я не могу получить адрес функции с помощью GetProcAddress().Вот мой код:

void callMyDll()
{
 HINSTANCE hDll;

 hDll=LoadLibrary(_T("MyDll.dll");

 if(hDll!=NULL)
 {
  cout<<"\n DLL Loaded \n";
 }
 else
  cout<<"\n DLL Not loaded\n"

 typedef void (__stdcall *MyFunction)(bool)

 Myfunction mf1 = (MyFunction) GetProcAddress(hDll, "MyFunction");

 if (mf1!=NULL)
  cout<<"\n Function Loaded Successfully \n";
 else
  cout<<"\n Function not loaded \n";

 FreeLibrary(hDll);
}

Я получаю вывод в виде:

DLL Loaded
Function not loaded

Но когда я пытаюсь с известными DLL, такими как glut32.dll и его функции, он работает нормально.

Я думаю, что это может быть проблема с его функцией, как

void pascal MyFunction(BOOL);

Кто-нибудь может мне помочь в этом отношении?

Ответы [ 4 ]

2 голосов
/ 25 января 2012

Вам нужно использовать extern "C", чтобы предотвратить искажение имени и убедиться, что функция экспортирована:

extern "C" __declspec(dllexport) void Myfunction(BOOL);

Для просмотра экспорта из вашей DLL вы можете использовать утилиту dumpbin.exe, поставляемую с Visual Studio:

dumpbin.exe /EXPORTS MyDll.dll

Это будет список имен всех экспортируемых символов.

В дополнение к этому не указан ни один из следующих переключателей компилятора:

Gz __stdcall calling convention: "Myfunction" would be exported as Myfunction@4
Gr __fastcall caling convention: "Myfunction" would be exported as @Myfunction@4

Примечание: я думаю, что последний символ зависит от версии компилятора, но все еще не просто "Myfunction".

1 голос
/ 25 января 2012

Процесс экспорта DLL зависит от искажения имени и оформления.Долгое устаревшее 16-битное pascal соглашение о вызовах эквивалентно stdcall на 32-битных платформах.

Прежде всего вы должны использовать extern "C", чтобы указать связь C и отключить искажение имени.

Однако ваша функция будет по-прежнему подлежать украшению имени .Если вы экспортируете его с __declspec(dllexport), тогда он будет экспортирован с именем _Myfunction@4.Если вы хотите экспортировать его по его истинному имени, вам нужно использовать файл .def.

Тем не менее, сохраняется вероятность того, что вы вообще не экспортировали функцию из DLL.Используйте Dependency Walker , чтобы проверить, был ли он экспортирован, и если да, то по какому имени.

0 голосов
/ 25 января 2012

Символ будет украшен, поэтому он никогда не будет называться MyFunction, более вероятно, _MyFunction@4.Вы можете быстро проверить это, используя что-то вроде dumpbin .

Вы можете прочитать больше о калечении здесь , если вы хотите избежать искажения, вам нужно использовать def файл для указания имен символов (или порядковых номеров).

0 голосов
/ 25 января 2012

Почему вы используете pascal соглашение о вызовах? Возможно, это изменит названия символов, и если это так, возможно, вам придется принять это во внимание.

...