各メソッド名に割り当てられる装飾名を見つけるにはどうすればよいですか? DLL でエクスポートできるように、装飾された名前が何であるかを調べようとしています。
6 に答える
.DEF ファイルはまだ使用されていますか?
.DEF ファイルは忘れてください。それらは過去のものです。
__declspec(dllimport/dllexport) を使用して、C 関数または C++ シンボルである関数をエクスポートします。
装飾されていない名前が本当に必要な場合は、Greg Hewgill によって提案されているように、__declspec(dllimport/dllexport) キーワードを extern "C" と組み合わせて使用すると、それらのシンボルの装飾が取り除かれます...
C++ 装飾を削除してもよろしいですか?
これにはいくつかの正当な理由があります: C コードで使用されるコードをエクスポートしたい、または別のコンパイラでコンパイルされたモジュールから DLL を使用したい。
2 つ目の理由として、代わりにコンパイラごとに 1 つの DLL を生成し、装飾を維持します。
それらの理由は別として、なぜ装飾を取り除きたいのですか?
C++ の装飾/名前マングリングは悪ではない
まったく逆です。
1 つのコンパイラで作業している場合 (そして、extern "C" のものではなく、装飾された名前を使用したいので、そうしていると思います)、C++ の装飾/名前マングリングを維持します。
このようにして、名前空間、クラス、関数/メソッドのオーバーロードなど、C++ の機能をフルに活用できるようになります。
それでも、シンボルの装飾を手作業で行うのは大惨事の元です。dllexport を使用して、さらに別の (.DEF) ファイルを処理することなく、シンボルをエクスポートします。
この質問はかなり似ています: Exporting DLL C++ Class , question about .def file . __declspec(dllexport)
簡単にまとめると、メソッドをエクスポートする作業をコンパイラに任せたいと思うでしょう。
Microsoft は、コンパイラのバージョンごとに関数名のマングリング (または「装飾された名前」と呼ばれる) の方法を変更しているため、マングルされた名前を手動でエクスポートしようとすると、将来のメンテナンスの問題が発生する可能性があります。「msvc 装飾名」をグーグルで検索すると、役立つリンクがいくつかありますが、保証はありません。
C++ の名前マングリングは、異なるコンパイラ間で一致するものではなく ( Greg Hewgillが述べたように、同じベンダーのコンパイラのバージョン間でも変更される可能性があります)、C++ の標準バイナリ インターフェイスがないため、通常、C++ をエクスポートすることはお勧めできません。 DLL からの関数。例外は、DLL がそれを使用するアプリケーションにかなり密接にバインドされ、バージョン管理されている場合です。
別の方法は、エクスポートされた関数を として宣言することextern "C"
です。
オブジェクト ファイルでdumpbinを使用すると、オブジェクトで使用されているすべてのメソッドを見つけることができます。使用方法は次のとおりです
dumpbin /symbols File.obj
VS2005には、関数内に配置されたときに装飾された名前の文字列を返すプリプロセッサマクロFUNCDNAMEがあります。ただし、これは非標準です。C99標準にはそのための機能があり、コンパイラがそれをサポートしているかどうかはわかりません。
(なぜoアンダースコアが正しく表示されないのですか??)
(編集:)これは最近同様の議論で明らかになった。
前の 2 人の回答者Greg HewgillとMike Bのアドバイスに従うべきだと思いますが、Microsoft ツール チェーンを使用していて、装飾された名前を本当に知りたい場合は...
- __declspec(dllexport)を使用して .lib および .dll ファイルを作成します。
- dumpbin /exports を使用して、dll によってエクスポートされた名前を調べます。
- __declspec(dllexport)を削除して、 .defファイルに手動でシンボルをエクスポートできるようになりました。