2013-03-18 46 views
1

我創建了一個DLL文件(helloWorld.dll):調用DLL ++文件

#define WIN32_LEAN_AND_MEAN 
#include <windows.h> 

#define DLL_FUNC extern "C" __declspec(dllexport) 

DLL_FUNC int __stdcall Hello() { 
    MessageBox(HWND_DESKTOP, "Hello, world", "MEssage", MB_OK); 
    return 0; 
} 

之後,我創建了一個CPP,我想調用(useDLL.cpp)

#include <windows.h> 
#include <stdio.h> 

int main() { 
    typedef void (*pfunc)(); 
    HINSTANCE hdll = LoadLibrary("HelloWorld.dll"); 
    pfunc Hello; 
    Hello = (pfunc)GetProcAddress(hdll, "hello"); 
    Hello(); 
    return 0; 
} 

如何調用Hello()函數?

+0

請參閱['GetProcAddress()'](http://msdn.microsoft.com/en-gb/library/windows/desktop/ms683212%28v=vs.85%29.aspx)參考頁,有一個例如它。 – hmjd 2013-03-18 17:15:54

+1

使用LoadLibrary是困難的方式 - 如果您不知道該DLL是否存在(或者可能稱爲),則可以使用LoadLibrary。如果你沒有這些特殊需求,有一種簡單的方法可以讓編譯器/鏈接器爲你做所有的工作。 – Elemental 2013-03-18 17:21:00

+0

「HWND_DESKTOP」的用途是什麼? – 2013-03-18 17:25:17

回答

5

在問題中的代碼包含了一些錯誤:

  1. LoadLibrary回報HMODULE和不是HINSTANCE
  2. 函數指針具有錯誤的返回值和不正確的調用約定。
  3. 函數名稱區分大小寫,您必須考慮名稱裝飾。
  4. 你根本沒有檢查錯誤。您的代碼可能在撥打GetProcAddress時失敗,返回NULL,然後在嘗試調用NULL處的函數時發生炸彈。

所以,你需要的東西是這樣的:

typedef int (__stdcall *HelloProc)(); 
.... 
HMODULE hdll = LoadLibrary("HelloWorld.dll"); 
if (hdll == NULL) 
    // handle error 
HelloProc Hello = (HelloProc)GetProcAddress(hdll, "[email protected]"); 
if (Hello == NULL) 
    // handle error 
int retval = Hello(); 

函數名飾,因爲你使用__stdcall。如果您使用過__cdecl或.def文件,那麼就沒有裝飾。我假設MSVC裝飾。看起來裝飾與編譯器mingw不同,函數名爲"[email protected]"

坦率地說,使用.lib文件而不是調用LoadLibraryGetProcAddress要容易得多。如果可以的話,我現在可以切換到這種方式。

+0

使用'extern「C'''__stdcall'不會裝飾導出的名稱。正如預期的那樣,正確的導出名稱將是'「Hello」。 – 2013-03-18 17:32:08

+0

感謝您的回覆,我修改了我的代碼,請參閱 – David 2013-03-18 17:34:53

+0

您需要修飾名稱。該函數被導出爲「_Hello @ 0」。再看看我的答案。 – 2013-03-18 17:36:04