我用一个名为“ 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”。
您导出的函数被视为C ++函数(由于* .cpp文件扩展名),因此C ++ name mangling用于修饰导出的函数名称。如果使用Microsoft的Dependency Walker工具检查创建的DLL,则将看到函数的全名。
您既可以在导入代码中使用该修饰名称,也可以强制编译器以C样式(即您当前导入代码期望的未经修饰的形式)导出函数。
您可以通过在函数签名中添加extern "C"
来告诉编译器这样做。像这样的东西:
extern "C" D3D_API_API void render();
现在您的导入代码应该可以正常工作了。
正如对答案的评论所说:
使用'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();