GCC C++ 链接器错误:未定义对 'vtable for XXX' 的引用,未定义对 'ClassName::ClassName()' 的引用
我正在使用 Eclipse-CDT 在 Ubuntu x64 上设置 C++ 项目.我基本上是在打个招呼,并链接到一个商业 3rd 方库.
我已经包含了头文件,链接到他们的库,但我仍然遇到链接器错误.除了明显的问题之外,这里是否还有一些可能的问题(例如,我 99% 确定我正在链接到正确的库).
- 有没有办法确认我链接的静态库是 64 位的?
- 有没有办法确认该库具有我期望它具有的类(和方法)?
Eclipse 说:
<上一页>构建目标:LinkProblem调用:GCC C++ 链接器g++ -L/home/notroot/workspace/somelib-3/somelib/target/bin -o"LinkProblem" ./src/LinkProblem.o -lsomelib1 -lpthread -lsomelib2 -lsomelib3./src/LinkProblem.o:在函数main"中:/home/notroot/workspace/LinkProblem/Debug/../src/LinkProblem.cpp:17:未定义对SomeClass::close()"的引用./src/LinkProblem.o:在函数SomeOtherClass"中:/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148:未定义对SomeClass::SomeClass()"的引用/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148:未定义对用于 SomeOtherClass 的 vtable"的引用/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:151:未定义对SomeClass::~SomeClass()"的引用./src/LinkProblem.o:在函数~SomeOtherClass"中:/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140:未定义对用于 SomeOtherClass 的 vtable"的引用/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140:未定义对SomeClass::~SomeClass()"的引用/home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140:未定义对SomeClass::~SomeClass()"的引用collect2: ld 返回 1 个退出状态make: *** [LinkProblem] 错误 1 解决方案假设这些方法在其中一个库中,它看起来像是一个排序问题.
将库链接到可执行文件时,它们按照声明的顺序完成.
此外,链接器将仅采用解决当前未解决的依赖项所需的方法/功能.如果随后的库随后使用对象最初不需要的方法/函数,您将缺少依赖项.
它是如何工作的:
- 获取所有目标文件并将它们组合成一个可执行文件
- 解决目标文件之间的任何依赖关系.
- 按顺序排列每个库:
- 检查未解决的依赖关系,看看 lib 是否解决了它们.
- 如果是这样,将所需部分加载到可执行文件中.
例子:
对象需要:
- 打开
- 关闭
- 批量读取
- 批量写入
Lib 1 提供:
- 打开
- 关闭
- 阅读
- 写
Lib 2 提供
- BatchRead(但使用 lib1:read)
- BatchWrite(但使用 lib1:write)
如果这样链接:
<块引用>gcc -o plop plop.o -l1 -l2
那么链接器将无法解析读写符号.
但如果我像这样链接应用程序:
<块引用>gcc -o plop plop.o -l2 -l1
然后它将正确链接.由于 l2 解决了 BatchRead 和 BatchWrite 依赖项,但还添加了两个新的依赖项(读取和写入).当我们与 l1 链接时,所有四个依赖项都将得到解决.
I'm setting up a C++ project, on Ubuntu x64, using Eclipse-CDT. I'm basically doing a hello world and linking to a commerical 3rd party library.
I've included the header files, linked to their libraries, but I still get linker errors. Are there some possible problems here other than the obvious (e.g. I am 99% sure I'm linking to the correct library).
- Is there a way to confirm the static libraries I am linking to are 64bit?
- Is there a way to confirm that the library has the class (and methods) I am expecting it to have?
Eclipse says:
Building target: LinkProblem Invoking: GCC C++ Linker g++ -L/home/notroot/workspace/somelib-3/somelib/target/bin -o"LinkProblem" ./src/LinkProblem.o -lsomelib1 -lpthread -lsomelib2 -lsomelib3 ./src/LinkProblem.o: In function `main': /home/notroot/workspace/LinkProblem/Debug/../src/LinkProblem.cpp:17: undefined reference to `SomeClass::close()' ./src/LinkProblem.o: In function `SomeOtherClass': /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148: undefined reference to `SomeClass::SomeClass()' /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148: undefined reference to `vtable for SomeOtherClass' /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:151: undefined reference to `SomeClass::~SomeClass()' ./src/LinkProblem.o: In function `~SomeOtherClass': /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `vtable for SomeOtherClass' /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `SomeClass::~SomeClass()' /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `SomeClass::~SomeClass()' collect2: ld returned 1 exit status make: *** [LinkProblem] Error 1
解决方案
Assuming those methods are in one of the libs it looks like an ordering problem.
When linking libraries into an executable they are done in the order they are declared.
Also the linker will only take the methods/functions required to resolve currently outstanding dependencies. If a subsequent library then uses methods/functions that were not originally required by the objects you will have missing dependencies.
How it works:
- Take all the object files and combine them into an executable
- Resolve any dependencies among object files.
- For-each library in order:
- Check unresolved dependencies and see if the lib resolves them.
- If so load required part into the executable.
Example:
Objects requires:
- Open
- Close
- BatchRead
- BatchWrite
Lib 1 provides:
- Open
- Close
- read
- write
Lib 2 provides
- BatchRead (but uses lib1:read)
- BatchWrite (but uses lib1:write)
If linked like this:
gcc -o plop plop.o -l1 -l2
Then the linker will fail to resolve the read and write symbols.
But if I link the application like this:
gcc -o plop plop.o -l2 -l1
Then it will link correctly. As l2 resolves the BatchRead and BatchWrite dependencies but also adds two new ones (read and write). When we link with l1 next all four dependencies are resolved.
相关文章