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