c ++未定义的引用与静态库
我试图从一个类,但尝试使用它,我总是得到错误与任何未定义的引用静态库。 我进行的方式是创build对象文件
g++ -c myClass.cpp -o myClass.o
然后包装
ar rcs myClass.lib myClass.o
总之,我明显缺less一些东西。 我敢打赌,这是符号的东西。 感谢您的任何build议,我知道这是最有可能的东西,我可以找出如果阅读一些教程,如果再次困扰愚蠢的东西,抱歉:)
编辑:
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
这可能是链接顺序问题。 当GNU链接器看到一个库时,它会丢弃它不需要的所有符号。 在这种情况下,您的库出现在.cpp文件之前,因此库在编译.cpp文件之前被丢弃。 做这个:
g++ -o main.exe main.cpp -L. -lmylib
要么
g++ -o main.exe main.cpp myClass.lib
Microsoft链接器不考虑命令行上库的sorting。
另一个可能的原因是:忘记extern "C"
。
我碰到这个,因为我试图链接一个C静态库的C程序。 该库的头没有extern "C"
所以链接器正在寻找一个损坏的函数名称,并且该库实际上具有未加载的函数名称。
花了一段时间才弄清楚发生了什么,所以我希望这能帮助别人。
使用:
g++ -o main.exe main.cpp myClass.lib
使用库path和-l标志充满了问题,但是如果你必须这么做的话,把你的库重命名为libmylib.a,然后编译为:
g++ -o main.exe main.cpp -L. -lmylib
还要注意,由于可移植性原因,在源文件或输出文件的名称中使用混合大小写通常是一个坏主意。
这应该避免链接错误,并创build.so共享库:
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
这是链接器如何优化输出代码的问题。 让我们假设我们有一个使用两个库的可执行文件: 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从不在可执行文件中使用。
- 在Windows的情况下,链接器的工作原理是这样的:我有两个可执行文件,它们使用一些库文件和可执行文件中使用的所有符号,所有库都是lib_A1和lib_B1 。 因此,我将需要这两个符号,其余是不必要的。 我将取消定义lib_A2和lib_B2
- 在Linux的情况下,如果你连接Lib_A之前像Lib_A这样:
g++ .... -lLib_B -lLib_A
链接器的工作原理是这样的:我有可执行文件首先链接Lib_B 。 我没有看到可执行文件使用符号Lib_B1和Lib_B2 。 他们是不需要的,因此我将无法定义他们。 稍后连接器见。 哦,我有另一个库Lib_A 。 我可以看到可执行文件使用符号Lib_B1 。 我会保留它,并取消定义未使用的符号Lib_B2 。 它没有看到Lib_B1使用Lib_A1 ,这已经是未定义的了。 - 在linux的情况下,如果你在Lib_B之前连接Lib_A ,像这样:
g++ ... -lLib_A -lLib_B
链接器的工作方式如下:我有可执行文件,首先链接Lib_A 。 哦,我可以看到可执行文件使用Lib_A1 。 我会保留它们并取消定义Lib_A2 。 后来它可以看到。 哦,我有另一个库Lib_B 。 我可以看到现在可执行已经链接的符号,使用Lib_B1 ,我会保留它们。 结果它保留了Lib_B1和Lib_A1 ,以及未定义的Lib_B2和Lib_A2 。