我正在尝试从类中创建一个静态库但是在尝试使用它时,我总是会遇到任何未定义引用的错误。我继续的方式是创建像
这样的目标文件g++ -c myClass.cpp -o myClass.o
然后用
打包ar rcs myClass.lib myClass.o
我一般都会忽略这一点。我打赌这是符号的东西。 感谢您的任何建议,我知道这很可能是我在读一些教程时会发现的事情,如果再次打扰愚蠢的东西就很抱歉:)
myClass.h:
class myClass{
public:
myClass();
void function();
};
myClass.cpp:
#include "myClass.h"
myClass::myClass(){}
void myClass::function(){}
程序使用类:
#include "myClass.h"
int main(){
myClass mc;
mc.function();
return 0;
}
最后我像这样编译:
g++ -o main.exe -L. -l myClass main.cpp
错误只是经典:
C:\Users\RULERO~1\AppData\Local\Temp/ccwM3vLy.o:main.cpp:(.text+0x31): undefined
reference to `myClass::myClass()'
C:\Users\RULERO~1\AppData\Local\Temp/ccwM3vLy.o:main.cpp:(.text+0x3c): undefined
reference to `myClass::function()'
collect2: ld returned 1 exit status
答案 0 :(得分:103)
这可能是 链接顺序问题。当GNU链接器看到库时,它会丢弃它不需要的所有符号。在这种情况下,您的库出现在.cpp文件之前,因此在编译.cpp文件之前将丢弃该库。这样做:
g++ -o main.exe main.cpp -L. -lmylib
或
g++ -o main.exe main.cpp myClass.lib
Microsoft链接器不考虑命令行上的库的排序。
答案 1 :(得分:20)
另一个可能的原因:遗忘extern "C"
。
我遇到了这个,因为我试图将C ++程序与C静态库链接起来。库的头部没有extern "C"
,因此链接器正在寻找一个受损的函数名,并且该库实际上具有未编码的函数名。
花了一段时间才弄明白发生了什么事,所以我希望这有助于其他人。
答案 2 :(得分:5)
使用:
g++ -o main.exe main.cpp myClass.lib
使用库路径和-l标志充满了问题,但如果必须这样做,请将库重命名为libmylib.a,然后编译为:
g++ -o main.exe main.cpp -L. -lmylib
另请注意,出于可移植性的原因,在源文件或输出文件的名称中使用混合大小写通常是个坏主意。
答案 3 :(得分:5)
这是链接器如何优化输出代码的问题。 让我们假设我们有一个使用两个库的可执行文件: Lib_A 和 Lib_B 。 Lib_A 取决于 Lib_B Lib_A 定义符号: Lib_A1 和 Lib_A2 , Lib_B 定义符号 Lib_B1 和 Lib_B2 。 现在假设可执行文件仅使用符号 Lib_A1 , Lib_A1 使用 Lib_B 中定义的符号 Lib_B1 。符号 Lib_B1 从不在可执行文件中使用。
g++ .... -lLib_B -lLib_A
链接器的工作方式如下:我的可执行文件首先链接 Lib_B 。我没有看到可执行文件使用符号 Lib_B1 或 Lib_B2 。它们是不必要的,因此我将取消定义它们。后来链接器看到了。哦,我有另一个库 Lib_A 。我可以看到可执行文件使用符号 Lib_B1 。我将保留它并取消定义未使用的符号 Lib_B2 。它没有看到 Lib_B1 使用 Lib_A1 ,这已经是未定义的。g++ ... -lLib_A -lLib_B
链接器的工作方式如下:我的可执行文件首先链接 Lib_A 。哦,我可以看到可执行文件使用 Lib_A1 。我将保留它们并取消定义 Lib_A2 。后来它可以看到。哦,我有另一个库 Lib_B 。我可以看到现在可执行的已经链接的符号,使用 Lib_B1 ,我会保留它们。因此,它保留 Lib_B1 和 Lib_A1 ,以及未定义的 Lib_B2 和 Lib_A2 。答案 4 :(得分:1)
这应避免链接错误并创建.so共享库:
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true