GetProcAddress无法找到我的函数

时间:2010-04-08 17:04:34

标签: dll getprocaddress

我用一个名为“render()”的函数创建了一个DLL,我想将它动态加载到我的应用程序中,但是GetProcAddress找不到它。这是DLL .h:

#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;
}

我的目标是使用统一的API通过自己的.DLL制作支持D3D和OpenGL的3D引擎。我在记事本中查看了.dll,并且有一个字符串“render”。

2 个答案:

答案 0 :(得分:10)

导出的函数被视为C ++函数(因为* .cpp文件扩展名),所以C ++ name mangling用于装饰导出的函数名。如果您使用Microsoft的Dependency Walker工具检查您创建的DLL,您将看到函数全名。

您可以在导入代码中使用该装饰名称,也可以强制编译器以C样式导出您的函数,即以当前导入代码所需的未修饰形式导出。

您可以通过在函数签名中添加extern "C"来告诉编译器。像这样:

extern "C" D3D_API_API void render();

现在,您的导入代码应该可以正常运行。

答案 1 :(得分:0)

如对答案的评论所述:

使用'extern“ C”'将删除任何C ++名称修饰,但仍然保留 C名字整齐。为了导出纯名称,您应该查看 使用.DEF文件。看到 blogs.msdn.microsoft.com/oldnewthing/20120525-00/?p=7533

您需要向项目中添加一个扩展名为.DEF的新文件,其内容与此类似:

LIBRARY      "MyRenderLib"

EXPORTS
render

然后在您的DLL标头中,您不使用__declspec(dllexport),而仅使用extern“ C”

extern "C" void render();