我用一个名为“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”。
答案 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();