c ++ - 对现有函数的未定义引用

时间:2015-03-25 06:04:13

标签: c++ linker

好吧,我正在开发一个小型网络库,用于我的另一个应用程序。我已经在NetStream.h中声明了一个函数,如下所示:

class NetStream;
class NetStream {
public:
  static NetStream *connect(char *ip, char *port, char** error);
  ...
}

在我的NetStream.cpp中,我已经使用相同的原型定义了它:

NetStream* NetStream::connect(char *ip, char *port, char** error) {
  ...
}

当我objdump我的libNetLib.a时,我可以看到NetStream :: connect被定义:

$ objdump -Ct NetLib/libNetLib.a | grep 'connect' #demangled names
000000000000031a g     F .text  00000000000001b4 NetStream::connect(char*, char*, char**)
0000000000000000         *UND*  0000000000000000 connect

$ objdump -t NetLib/libNetLib.a | grep 'connect' #mangled names
000000000000031a g     F .text  00000000000001b4 _ZN9NetStream7connectEPcS0_PS0
0000000000000000         *UND*  0000000000000000 connect

在使用我的NetLib的应用程序的目标文件中,objdump显示它导入了一个具有相同原型的函数:

$ objdump -Ct connection.cpp.o | grep 'connect'
...
0000000000000000         *UND*  0000000000000000 NetStream::connect(char*, char*, char**)
...

$ objdump -t connection.cpp.o | grep 'connect'
...
0000000000000000         *UND*  0000000000000000 _ZN9NetStream7connectEPcS0_PS0_
...

但是当我将应用程序与g ++ 4.9.2链接时,我收到此错误:

connection.cpp:(.text+0x52): undefined reference to `NetStream::connect(char*, char*, char**)'

当CMake尝试链接它时,以及当我使用以下命令链接它时,会发生这种情况:

$ g++ connection.cpp.o -L NetStream.cpp.o -o /tmp/tst

我得到了相同的未定义引用(以及一堆其他未定义的引用,因为还有其他东西要链接在那里,我没有链接那里)。

我看了一下,看到这通常是在函数原型中的const指针不同时引起的,但这里没有const。

真正的问题是什么?

2 个答案:

答案 0 :(得分:3)

  

g++ connection.cpp.o -L NetStream.cpp.o -o /tmp/tst

这个命令行完全是假的。试试这个:

g++ connection.cpp.o -LNetLib -lNetLib -o /tmp/tst

或者这个:

g++ connection.cpp.o NetLib/libNetLib.a -o /tmp/tst

<强>更新

  

这里的真正的问题是什么?

真正的问题是您的链接命令行不正确(如上所述)。

  

我无法真正编译我的代码...

编译不是问题,链接是。

据推测,您无法构造正确的链接命令,因为您正在使用CMake,而CMake构造了伪造的链接命令行。

由于知道 CMake有效,我们必须假设您的CMakefile是根本原因。很遗憾,您尚未展示自己的CMakefile

你应该问一个单独的问题,例如:“我有以下CMakefile,这会产生以下链接,这个答案告诉我这是假的。我的CMakefile有什么问题?“

答案 1 :(得分:2)

你真的需要查找g ++的命令行选项的含义,因为你严重滥用它们。

-L 目录告诉链接器在目录中查找库文件。除非你有一个名为“NetStream.cpp.o”的目录(这是不太可能的),并且你在该目录中指定要链接的库(你没有),你的命令行是乱码。

您的命令行有效地告诉链接器在目录中查找库文件,但不提供有关要链接的库的任何信息。因此链接器甚至无法访问您的“NetLib.a”。

假设你在目录中有一个名为NetLib.a的库(相对于调用g ++时的工作目录),名为NetLib,那么就像雇佣俄语指出的那样 - 你要么做“g ++ connection.cpp.o - LNetLib -lNetLib -o / tmp / tst“链接到库或”g ++ connection.cpp.o NetLib / libNetLib.a -o / tmp / tst“。