関数呼び出しの内部を理解する(1)

内部を知らない人はWindowsのDLLで関数が正しく呼べないことが多いです。
また、UNIXを使う方も知識として覚えておいて損はないです。

C++の関数呼び出しについては、コンパイラとリンカが関係しています。



コンパイラは関数に装飾された名前(以下、装飾名)を作成します。
リンカは装飾名を使って、別ファイルにある関数や変数を参照します。

まず、この装飾名を調べる方法を紹介します。
コンパイラが付けた名前なので、調査対象は以下のファイルになります。

  • オブジェクトファイル(*.obj, *.o)
  • ライブラリファイル(*.lib, *.dll, *.so)

確認しておきますと、ライブラリファイルとはオブジェクトファイルの集合です。

名前の調査には、Windowsの場合「dumpbin」コマンド(※1)を使います。
UNIXの場合は「ld」コマンド辺りだと思います。

ここではdumpbinを利用します。

> dumpbin /SYMBOLS msvcrt.lib

002 00000000 UNDEF  notype       External     | _strcpy
・・・(略)
002 00000000 UNDEF  notype       External     | ?_wopen@@YAHPB_WHH@Z (int __cdecl _wopen(wchar_t const *,int,int))

strcpy関数に対して「_strcpy」という装飾名を使っている事が確認できます。
しかし、wopenは「?_wopen@@YAHPB_WHH@Z」です。

実は「呼び出し規約」によって装飾が違うのです。
つまり、関数を正しく呼び出すのに、関数名だけでは不十分な場合があります

このように名前を装飾することをマングリング(mangling)と呼び、逆をデマングリング(demangling)と呼ぶ事も覚えておいてください。

次回は「呼び出し規約」について説明していきます。



※1 GUIツールである「Dependency Walker」を使う人も多いです。

Leave a Reply

最初のコメントを頂けますか?

更新通知を受け取る »
avatar
wpDiscuz