C++(拡張子cpp)のソースファイルをビルドして作成したDLLでエクスポートされた関数は名前マングリング(名前修飾)されます。本投稿では、名前マングリングについての理解をまとめます。
名前マングリングとは
名前マングリング、または名前修飾する、とは、C++の以下機能のために導入されている処理の1つです。
- クラス
- 多重定義(オーバーロード)
例えば、C言語でDLLを作成する場合、同一DLL内に同名の関数は存在できません。しかし、C++ではオーバーロードするために、同一名の関数が存在することを許したい。このため、引数なども含めた形で、実際の関数名を修飾(マングリング)することで区別している、というわけです。
確認方法
名前マングリングされているかどうかはdumpbinを実行することで確認できます。
〉dumpbin /exports DLLファイル名
実行結果は以下のようになります。
上記の例では、”YAXXZ”という文字列でマングリングされていますが、これは、下記ソースコードの通り、『void function(void)』の形式に対する修飾方法になります。
#include "pch.h"
#include <stdio.h>
__declspec (dllexport) void SampleApi1(void)
{
printf("Hello,Sample1\n");
}
以下の通り、ソースを修正すると、どうなるかを確認します。(SampleApi1の引数と戻り値の型をvoidからintへ変更します。)
#include "pch.h"
#include <stdio.h>
__declspec (dllexport) int SampleApi1(int a)
{
printf("Hello,Sample1\n");
return 0;
}
名前マングリングの内容が変化することが分かります。
名前マングリングを回避したい時
DLLのプロジェクト全体がC言語として作られているが、改造でC++のソースを追加した場合には、名前マングリングさせたくないかもしれません。その際は、以下のいずれかの方法で対処してください。
- 拡張子を『.c』としてビルドする。
- 関数名に『extern “C”』をつけてビルドする。
参考リンク
Decorated names
Learn more about: Decorated names
コメント