0

我已经制作了一个自定义 c++ 框架,我试图在使用 Xcode 4 开发的 c++ 应用程序中使用它。但是,我最近遇到了一些麻烦:我遇到了三个无法解决的链接器错误,如下所示:

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 并实现了此方法。第三个类 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())时它可以正常工作,所以如果我让在 header(.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 回答