Ale*_*ack 70 c++ linker g++ eclipse-cdt
我正在使用Eclipse-CDT在Ubuntu x64上设置一个C++项目.我基本上是在打招呼世界并链接到商业第三方图书馆.
我已经包含了链接到其库的头文件,但我仍然遇到链接器错误.除了明显的问题之外,这里是否存在一些可能的问题(例如我99%肯定我正在链接到正确的库).
Eclipse说:
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
mgi*_*uca 166
这通常链接错误(在我的经验),意味着你已经覆盖在声明子类中的虚函数,但没有给出该方法的定义.例如:
class Base
{
virtual void f() = 0;
}
class Derived : public Base
{
void f();
}
Run Code Online (Sandbox Code Playgroud)
但是你还没有给出f的定义.使用该类时,会出现链接器错误.就像普通的链接器错误一样,这是因为编译器知道你在说什么,但链接器找不到定义.这只是一个非常难以理解的消息.
Mar*_*ork 74
假设这些方法位于其中一个库中,它看起来像一个排序问题.
将库链接到可执行文件时,它们按照声明的顺序完成.
此外,链接器将仅采用解析当前未完成的依赖项所需的方法/函数.如果后续库然后使用对象最初不需要的方法/函数,那么您将缺少依赖项.
这个怎么运作:
例:
对象需要:
Lib 1提供:
Lib 2提供
如果像这样链接:
gcc -o plop plop.o -l1 -l2
然后链接器将无法解析读写符号.
但如果我像这样链接应用程序:
gcc -o plop plop.o -l2 -l1
然后它将正确链接.由于l2解析了BatchRead和BatchWrite依赖项,但还添加了两个新的(读取和写入).当我们接下来与l1链接时,所有四个依赖关系都被解析.
Ric*_*ith 52
更改类时,Qt C++将显示此错误,使其现在继承自QObject(即,现在它可以使用信号/插槽).运行qmake -r将调用moc并修复此问题.
如果您通过某种版本控制与其他人合作,则需要对.pro文件进行一些更改(即添加/删除空白行).当其他人获得您的更改并运行make时,make将会看到.pro文件已更改并自动运行qmake.这将使您的队友免于重复您的挫败感.
pho*_*ord 15
对我来说问题变得相当模糊.我的班级看起来像这样:
//-----------------------------------------
// libbase.h
class base {
public:
base() { }
virtual ~base() { }
virtual int foo() { return 0; }
};
//-----------------------------------------
//-----------------------------------------
// libbase.cpp
#include "libbase.h"
//-----------------------------------------
//-----------------------------------------
// main.h
class derived : public base {
public:
virtual int foo() ;
};
//-----------------------------------------
//-----------------------------------------
// main.cpp
int main () {
derived d;
}
//-----------------------------------------
Run Code Online (Sandbox Code Playgroud)
问题出在链接器中.我的头文件在某个库中进入,但是所有的虚函数都在类声明中声明为'inline'.由于没有使用虚函数的代码(尚未),编译器或链接器忽略了将实际的函数体放在适当的位置.它也无法创建vtable.
在我从这个类派生的主代码中,链接器试图将我的类连接到基类和他的vtable.但vtable已被丢弃.
解决方案是在类声明之外声明至少一个虚函数体,如下所示:
//-----------------------------------------
// libbase.h
class base {
public:
base() { }
virtual ~base() ; //-- No longer declared 'inline'
virtual int foo() { return 0; }
};
//-----------------------------------------
//-----------------------------------------
// libbase.cpp
#include "libbase.h"
base::~base()
{
}
//-----------------------------------------
Run Code Online (Sandbox Code Playgroud)
小智 9
关于Qt4的问题,我无法使用上面提到的qmake moc选项.但无论如何这不是问题.我在类定义中有以下代码:
class ScreenWidget : public QGLWidget
{
Q_OBJECT // must include this if you use Qt signals/slots
...
};
Run Code Online (Sandbox Code Playgroud)
我不得不删除"Q_OBJECT"行,因为我没有定义信号或插槽.
小智 5
当我们简单地在基类中声明没有任何定义的虚函数时,也会发生此错误.
例如:
class Base
{
virtual void method1(); // throws undefined reference error.
}
Run Code Online (Sandbox Code Playgroud)
将上述声明更改为以下声明,它将正常工作.
class Base
{
virtual void method1()
{
}
}
Run Code Online (Sandbox Code Playgroud)