2010-04-08 133 views
3

我用名爲「render()」的函數做了一個DLL,我想動態地將它加載到我的應用程序,但GetProcAddress找不到它。這裏的DLL .H:GetProcAddress找不到我的函數

#ifdef D3D_API_EXPORTS 
#define D3D_API_API __declspec(dllexport) 
#else 
#define D3D_API_API __declspec(dllimport) 
#endif 

D3D_API_API void render(); 

而這裏的DLL的.cpp:

#include "stdafx.h" 
#include "D3D_API.h" 
#include <iostream> 

D3D_API_API void render() 
{ 
    std::cout << "method called." << std::endl; 
} 

下面是試圖使用該功能的應用程序:

#include "stdafx.h" 
#include <windows.h> 
#include <iostream> 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    HINSTANCE myDLL = LoadLibrary(L"D3D_API.dll"); 

    if (myDLL == NULL) { 
     std::cerr << "Loading of D3D_API.dll failed!" << std::endl; 
    } 

    typedef void (WINAPI *render_t)(); 

    render_t render = (render_t)GetProcAddress(myDLL, "render"); 

    if (render == NULL) { 
     std::cerr << "render() not found in .dll!" << std::endl; 
    } 
    return 0; 
} 

我的目標是做一個3D引擎,它使用統一的API通過自己的.DLL支持D3D和OpenGL。我看着記事本中的.dll文件,並有一個字符串「渲染」。

回答

9

您導出的函數被視爲C++函數(因爲* .cpp文件擴展名),因此C++ name mangling用於修飾導出的函數名稱。如果您從微軟使用Dependency Walker工具檢查您所創建的DLL,你會看到的功能全名。

您可以使用在你的導入代碼修飾名或強制編譯器導出功能,採用C風格的,那就是,在當前的導入代碼預計其未修飾的形式。

你可以告訴編譯器中加入extern "C"你的函數簽名這樣做。類似這樣的:

extern "C" D3D_API_API void render(); 

現在您的導入代碼應該像預期一樣工作。

+0

謝謝,定了! – SurvivalMachine 2010-04-09 17:56:02

+0

我嘗試在導入代碼中使用裝飾名稱,即GetProcAddress(myDLL,「0MyObject @ my_name_space @@ QAE @ XZ」);'並且返回值爲NULL。你確定這應該起作用嗎? – Benny 2014-02-19 13:07:55

+0

要添加到這一點,使用「外部‘C’」將消除任何C++名字改編,但仍然留下Ç名字改編。爲了導出普通名稱,您應該使用.DEF文件查看。見https://blogs.msdn.microsoft.com/oldnewthing/20120525-00/?p=7533 – njplumridge 2017-10-03 17:18:37