GetProcAddress找不到我的函数

问题描述 投票:5回答:2

我用一个名为“ 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”。

dll getprocaddress
2个回答
10
投票

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

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

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

extern "C" D3D_API_API void render();

现在您的导入代码应该可以正常工作了。


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();
© www.soinside.com 2019 - 2024. All rights reserved.