Undecorating names to see why a function can't be found
Undecorating names to see why a function can't be found
装飾されていない関数が見つからないエラー
元ネタ
“The Old New Thing : Undecorating names to see why a function can't be found”
http://blogs.msdn.com/oldnewthing/archive/2008/12/29/9255240.aspx
これは実際におきた問題です。
When I build my project, it compiles fine, but it fails during the link step with an unresolved external: program.obj : error LNK2001: unresolved external symbol "public: virtual wchar_t const * __thiscall UILibrary::PushButton::GetName(class UILibrary::StringHolder * *)" (?GetName@PushButton@UILibrary@@UAEPB_WPAPAVStringHolder@2@@Z) The function I'm trying to call exists in the source code for uilibrary.lib; I'm looking at it right now. And the definition in the source code matches the declaration in the header file: namespace UILibrary { ... class PushButton { public: virtual LPWSTR GetName(StringHolder **Holder); }; ... } Why can't the linker find it? (Other functions in uilibrary.lib link just fine.)
何かをみつける(リンクする)には、適切な場所を探す必要があり、
実際探している物はそこにないといけない。
そしてそれがそこにある場合、確認できないといけない。
まず適切な場所をみてみると、それは正しく配置されているようにみうけられる。
リンカーはどうにかuilibrary.libの中で他のものを見つけたのでそれを見ている。
次にあなたは、本当に正しい場所を見ているだろうか?
私は、uilibrary.libをバイナリエディタで確認しましたしかし、
そこでは文字列を使う事ができません。
もしあなたが装飾文字列がほしいならば、link /dump /headersを実行します。
そして、GetName@PushButtonがそのライブラリのメンバ関数として存在するならば
当然確認できるとと思い探してみました。
確かに関数はある、だがそれは見た目だけで実は違う。
GetName@PushButton@UILibrary@@UAEPBGPAPAVStringHolder@2@@Z
あら?そのシンボルは、そこに全く存在していないのでみつからないではないか!!
表面的に似ているが実は違った装飾がされている。
私たちは、undnameを利用してこの名前をコンバートして調査をしてみた。
C:\> undname ?GetName@PushButton@UILibrary@@UAEPBGPAPAVStringHolder@2@@Z
public: virtual unsigned short const * __thiscall
UILibrary::PushButton::GetName(class UILibrary::StringHolder * *)
2つの関数をよく見てほしい。
一方は、wchar_t* const *を返すのに、片方は、unsigned short const *を
返す事になっている。
これではっきりした。
そのライブラリは、/Zc:wchar_t-* flagをつけてコンパイルされている。
これにより私達のプログラムは、wchar_tをネイティブ型として扱うが
利用したお客様のライブラリは、それが有効になっていないので、Windows.hを
includeしたときに、wchar_t -> unsigned shortとしてtypedefされたのだ。
よってあなたは、似たようなこのエラーのケースを解決する十分な知識を得た。
When I build my project, it compiles fine, but it fails during the link step with an unresolved external: program.obj : error LNK2019: unresolved external symbol "long __cdecl UILibrary::Initialize(bool)" (?Initialize@UILibrary@@YAJ_N@Z)
つまりこれは、long __stdcall UILibrary::Initialize(bool)に装飾されていない為だ。
Note:
undname プログラムや/Zc:wchar_t-スイッチは、マイクロソフトのVisualStudioC++
固有のものである。
もし、他のコンパイラを使う場合は、あなたは、ユーティリティソフトや
コマンドラインスイッチを適切に指定すべきである。
VisualStudioを使う場合、C/C++言語の設定におけるwchar_tをビルトインタイプとして
扱うという設定にあたることを伝えておこう。