2016-02-05 61 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功能名稱裝飾有一個前導下劃線,接着是@,然後在堆棧上傳遞的參數(以字節爲單位)的數目。在32位對齊的機器上,該數字總是4的倍數。 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'來避免這種裝飾。或者只需使用正確的名稱導入該功能。 –