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

c++ - Undefined Reference to Existing Function

好的,我正在开发一个小型网络库以用于我的另一个应用程序。我在 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_
...

但是当我 link 使用 g++ 4.9.2 的应用程序时,我得到这个错误:

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

这发生在 CMake 尝试 link 它时,当我使用以下命令 link 它时:

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

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

我看了一圈,发现这通常是函数原型中的 const 指针不同导致的,但这里没有 const。

这里真正的问题是什么?

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

更新:

What is the real problem here?

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

I can't really compile my code like that ...

编译不是这里的问题,linking 才是。

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

由于我们知道 CMake 有效,我们必须假定根本原因是您的 CMakefile。很遗憾,您还没有显示您的 CMakefile.

你应该问一个单独的问题,像这样:"I have the following CMakefile, which results in the following link line, which this answer tells me is bogus. What is wrong with my CMakefile?"

您确实需要查找 g++ 命令行选项的含义,因为您严重误用了它们。

-Ldirectory 告诉 linker 在 directory 中查找库文件。除非你有一个名为 "NetStream.cpp.o" 的目录(这不太可能)并且你将该目录中的库指定为 link(你没有)你的命令行是乱码。

您的命令行有效地告诉 link 用户在目录中查找库文件,但没有提供任何有关要 link 编辑的库的信息。所以你的 "NetLib.a" 甚至没有被 linker.

访问

假设您在名为 NetLib 的目录(相对于调用 g++ 时的工作目录)中有一个名为 NetLib.a 的库,然后 - 正如 Employed Russian 指出的那样 - 您需要做 "g++ connection.cpp.o -LNetLib -lNetLib -o /tmp/tst" 到 link 反对图书馆或 "g++ connection.cpp.o NetLib/libNetLib.a -o /tmp/tst".