代码之家  ›  专栏  ›  技术社区  ›  SurvivalMachine

GetProcAddress找不到我的函数

  •  4
  • SurvivalMachine  · 技术社区  · 16 年前

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

    #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”。

    1 回复  |  直到 16 年前
        1
  •  12
  •   Frank Bollack    16 年前

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

    您可以通过添加 extern "C"

    extern "C" D3D_API_API void render();
    

    现在您的导入代码应该像expexted一样工作。

        2
  •  0
  •   Dmitriy    6 年前

    正如对答案的评论所说:

    使用“外部”C“”将删除任何C++名称,但仍然会留下 C名mangling。为了导出普通名称,您应该查看 blogs.msdn.microsoft.com/oldnewthing/20120525-00/?p=7533

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

    LIBRARY      "MyRenderLib"
    
    EXPORTS
    render
    

    然后在DLL头中不使用\uu declspec(dllexport),而只使用extern“C”

    extern "C" void render();
    
    推荐文章