0

Xcode 4 を使用して開発された C++ アプリケーション内で使用しようとしているカスタム C++ フレームワークを作成しました。ただし、最近、いくつかの問題に遭遇しました。次のように、解決できない 3 つのリンカー エラーが発生しています。

Undefined symbols for architecture x86_64:
  "non-virtual thunk to netlib::base::BaseSocket::run()", referenced from:
   vtable for NetworkClient in network_client.o

このクラス NetworkThread をフレームワークで宣言しています。このクラスには抽象メソッド run() があります。フレームワーク内の別のクラスである BaseSocket は、NetworkThread から継承し、このメソッドを実装します。3 番目のクラスである NetworkClient は、フレームワーク自体ではなく、フレームワークを使用するアプリケーションで作成され、クラス BaseSocket から継承されますが、それをコンパイルすると、上記のリンカー エラーがトリガーされます。

私はリンカ エラーを解決する方法をきちんと知っていますが、ここでこれに関する奇妙な部分に移ります。クラス BaseSocket の実装の一部でしかリンカ エラーが発生しません。一部のメソッドは正常に動作します (追加した新しいメソッドでさえ、フレームワークとそのパスが正しく設定されている)。リンカー エラーを修正する回避策を見つけました。エラーが発生したときの (BaseSocket の) ヘッダー宣言は次のようになります: </p>

void run() override; // Will cause linker error

このようにヘッダーを変更すると (また、実装内のメソッドの名前も runX に変更すると)、正常に動作します。

void run() override { this->runX(); } 
void runX(); // Works like a charm!

派生データ フォルダーを削除し、プロジェクトを消去して、プロジェクトと共に配置されたビルド フォルダーを削除しました。

助言がありますか?

前もって感謝します!

更新:問題を要約すると、メソッドの名前が「run」の場合、リンカは実装を「見る」ことができないと言うかもしれませんが、別のもの (runX() など) を呼び出した場合は正しく機能します。ヘッダー (.h) ファイル内の run() の実装は、問題を修正するメソッド runX (cpp ファイルに実装) を呼び出します。コンパイラやリンカのバグのように思えます。

4

1 に答える 1

0

これは、vtables、仮想関数、および継承で何が起こっているかについての素晴らしい投稿です。

http://arsenmk.blogspot.com/2013/02/a-little-more-about-virtual-functions.html

また、コマンド ラインで「otool」および「nm」コマンドを使用して、リンカが参照する内容を確認できます。そのような:

$ nm /path/to/your.o 

シンボルのリストを出力します。ここで、「U」は未定義のシンボルを示します。次のようなものです。

000000000000001b T foo
0000000000000000 T main
                 U printf

nm コマンドのオプションと出力の概要を以下に示します。

http://pic.dhe.ibm.com/infocenter/aix/v7r1/index.jsp?topic=%2Fcom.ibm.aix.cmds%2Fdoc%2Faixcmds4%2Fnm.htm

nmコマンドの「シンボル値」とはどういう意味ですか?

于 2013-08-23T16:44:40.670 に答える