web-dev-qa-db-ja.com

DLLのエクスポートされた関数の名前変更を停止するにはどうすればよいですか?

「GetName」と呼ばれる関数をエクスポートするDLLを作成しようとしています。他のコードで、破損した関数名を知らなくてもこの関数を呼び出せるようにしたいのですが。

私のヘッダーファイルは次のようになります。

#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif

EXPORT TCHAR * CALLBACK GetName();

私のコードは次のようになります:

#include <windows.h>
#include "PluginOne.h"

int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
{
     return TRUE ;
}

EXPORT TCHAR * CALLBACK GetName()
{
    return TEXT("Test Name");
}

私がビルドするとき、DLLはまだ名前が "_GetName @ 0"の関数をエクスポートします。

何が悪いのですか?

29
Slapout

小さな修正-クリネットによる名前解決に成功

extern "C"

インポート時と同様にエクスポート側である必要があります。

extern "C"はprocの名前を "_GetName"に減らします。

さらに、.defファイルのセクションEXPORTSを使用して任意の名前を強制できます

23
Dewfy

これは、DLL __stdcall規約。 @N関数が引数として受け取るバイト数を示します -この場合、ゼロです。

DLLからのエクスポートに関するMSDNページ は、「関数の定義でキーワード__declspec(dllexport)」を使用する場合、「__ stdcall呼び出し規約を使用する」と具体的に述べています。

9
Mark Rushakoff

正解は次のとおりです。

extern "C" int MyFunc(int param);

そして

int MyFunc(int param);

は、異なる内部命名を使用する2つの宣言です。1つ目はCスタイル、2つ目はC++スタイルです。

c ++はより複雑なので(oop、オーバーロード、仮想関数など)、より複雑な命名を使用します。呼び出し規約は、cとc ++の両方の命名にも影響します。

__declspec(dllexport)を同じように使用すると、この両方の命名スタイルが適用されます。

エクスポートされたルーチンの名前のマングリングを省略したい場合は、モジュール定義ファイルをプロジェクトに追加し、それを入力します(この場合、dllexportをdeclspecする必要はありません)。

LIBRARY mylib
EXPORTS
  MyFunc

これにより、明示的な名前の装飾が省略されます(以下のサンプル)。

_MyFunc (c style, __cdecl)
_MyFunc@4 (c style, __stdcall)
?MyFunc@@YAHH@Z (c++ style, __cdecl)
?MyFunc@@YGHH@Z (c++ style, __stdcall)
6
sn0w

「-Wl、-kill-at」リンカースイッチを使用して、名前のマングリングを無効にすることができます。

たとえば、Code :: Blocksのカスタムリンカー設定で、次を追加します。-Wl、-kill-at

3
vga None