7

「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」という文字列がありました。

4

2 に答える 2

12

エクスポートする関数は(* .cppファイル拡張子のため)C ++関数として扱われるため、エクスポートされた関数名を装飾するためにC++名前マングリングが使用されます。MicrosoftのDependencyWalkerツールを使用して、作成したDLLを検査すると、関数のフルネームが表示されます。

インポートコードでその装飾された名前を使用するか、コンパイラに関数をCスタイルで、つまり現在のインポートコードが期待する装飾されていない形式でエクスポートするように強制することができます。

extern "C"関数のシグネチャに追加することで、コンパイラにそうするように指示できます。このようなもの:

extern "C" D3D_API_API void render();

これで、インポートコードはexpextedとして機能するはずです。

于 2010-04-09T13:09:04.150 に答える
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();
于 2020-03-21T12:59:31.557 に答える