2010-04-08 2 views
3

Я создал DLL с функцией «render()», и я хочу динамически ее загружать в приложение, но GetProcAddress не может ее найти. Вот DLL .h:GetProcAddress не может найти свои функции

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

Моя цель состоит, чтобы сделать 3D который поддерживает как D3D, так и OpenGL через свои собственные .DLL, используя унифицированный API. Я посмотрел .dll в блокноте, и появилась строка «render».

ответ

9

Функция, которую вы экспортируете, рассматривается как функция C++ (из-за расширения файла .cpp), поэтому C++ name mangling используется для украшения имени экспортируемой функции. Если вы используете инструмент Dependency Walker от Microsoft для проверки вашей созданной DLL, вы увидите полное имя функции.

Вы можете использовать это украшенное имя в своем импортном коде или заставить компилятор экспортировать вашу функцию в стиле C, то есть в своей незадекларированной форме, которую ожидает ваш текущий код импорта.

Вы можете сообщить компилятору об этом, добавив extern "C" к вашей функции. Что-то вроде этого:

extern "C" D3D_API_API void render(); 

Теперь ваш код импорта должен работать как expexted.

+0

Спасибо, что исправил это! – SurvivalMachine

+0

Я попытался использовать украшенное имя в коде импорта, то есть 'GetProcAddress (myDLL," ?? 0MyObject @ my_name_space @@ QAE @ XZ ");' и возвращаемое значение 'NULL'. Вы уверены, что это должно сработать? – Benny

+0

Чтобы добавить к этому, используя «extern», C "'удалит любое имя языка C++, но все равно оставит C имя mangling. Чтобы экспортировать простые имена, вы должны посмотреть на использование .DEF-файла. См. Https://blogs.msdn.microsoft.com/oldnewthing/20120525-00/?p=7533 – njplumridge