2016-02-05 7 views
0

я следующий код:C++ GetProcAddress не работает

typedef int (WINAPI* fnEngineStart)(); 


int __stdcall EngineStart() 
{ 
BOOL FreeResult = 0, RunTimeLinkSuccess = 0; //variables for later use 
HMODULE LibraryHandle = 0; //Here the handle to API module/dll will be stored. 
fnEngineStart fn = 0; 

LibraryHandle = AfxLoadLibrary(L"FlowEngine.dll"); //get the handle of our API module 
//so it will now be loaded. 
if (LibraryHandle != NULL) //if the library loading was successfull.. 
{ 
    fn = (fnEngineStart)GetProcAddress(LibraryHandle, 
     "fnEngineStart"); 
    if (RunTimeLinkSuccess = (fn != NULL)) //if operation was successful... 
    { 
     int ReturnValue = fn(); //call messageboxa function 
     //from user32.dll 
    } 
    else 
    { 
     MessageBox(0, L"Error", 0, 0); 
    } 
    FreeResult = FreeLibrary(LibraryHandle); 
    //from this process... 
    return FreeResult; //routine was successful 
} 
return EXIT_FAILURE; //else, it failed 
} 

Этот код прекрасно работает, например, user32.dll и MessageBoxA, но не моей собственной библиотеки DLL ...

int __declspec(dllexport) __stdcall fnEngineStart() 
{ 
    MessageBox(0, L"Succes!", 0, 0); 
    return 0; 
} 

Как мне сделать это работать и на мою собственную DLL? Спасибо заранее.

+0

GetProcAddress задает значение для GetLastError ... –

+0

И что код ошибки будет 127. Поскольку имя функции декорирован. Потенциально с использованием C++, но, безусловно, stdcall украшения. Либо используйте файл .def, либо, лучше, пусть имя будет искажено и импортирует его с помощью искаженного имени. –

ответ

0

Проблема, с которой вы имеете дело, - Name Mangling. Используйте extern "C", чтобы компилятор не исказил имя. Пример:

extern "C" int __declspec(dllexport) __stdcall fnEngineStart() 
{ 
    MessageBox(0, L"Succes!", 0, 0); 
    return 0; 
} 

Примечание: __stdcall функция имя декорированное с ведущим подчеркиванием, за которым следует @ и число (в байтах) аргументов, переданных в стек. Это число всегда будет кратным 4, на 32-битной выровненной машине. Source

Если ваш компилятор поддерживает его, вы можете сделать это в своей DLL, и все должно работать так, как вы сейчас это делаете.

extern "C" int __declspec(dllexport) __stdcall fnEngineStart() 
{ 
    #pragma comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__) 
    MessageBox(0, L"Succes!", 0, 0); 
    return 0; 
} 
+1

Там больше, чем это. Функция будет экспортироваться в виде '_fnEngineStart @ 0'. Вам нужно будет использовать файл .def или переключиться на 'cdecl', чтобы избежать этого украшения. Или просто импортируйте функцию с ее правильным именем. –