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_ALib_BLib_A依赖于Lib_B Lib_A定义符号: Lib_A1Lib_A2Lib_B定义符号Lib_B1Lib_B2 。 现在我们假设可执行文件只使用符号Lib_A1Lib_A1使用Lib_B中定义的符号Lib_B1 。 符号Lib_B1从不在可执行文件中使用。

  1. 在Windows的情况下,链接器的工作原理是这样的:我有两个可执行文件,它们使用一些库文件和可执行文件中使用的所有符号,所有库都是lib_A1lib_B1 。 因此,我将需要这两个符号,其余是不必要的。 我将取消定义lib_A2lib_B2
  2. 在Linux的情况下,如果你连接Lib_A之前像Lib_A这样: g++ .... -lLib_B -lLib_A链接器的工作原理是这样的:我有可执行文件首先链接Lib_B 。 我没有看到可执行文件使用符号Lib_B1Lib_B2 。 他们是不需要的,因此我将无法定义他们。 稍后连接器见。 哦,我有另一个库Lib_A 。 我可以看到可执行文件使用符号Lib_B1 。 我会保留它,并取消定义未使用的符号Lib_B2 。 它没有看到Lib_B1使用Lib_A1 ,这已经是未定义的了。
  3. 在linux的情况下,如果你在Lib_B之前连接Lib_A ,像这样: g++ ... -lLib_A -lLib_B链接器的工作方式如下:我有可执行文件,首先链接Lib_A 。 哦,我可以看到可执行文件使用Lib_A1 。 我会保留它们并取消定义Lib_A2 。 后来它可以看到。 哦,我有另一个库Lib_B 。 我可以看到现在可执行已经链接的符号,使用Lib_B1 ,我会保留它们。 结果它保留了Lib_B1Lib_A1 ,以及未定义的Lib_B2Lib_A2