带有静态库的 c++ 未定义引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2624238/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
c++ undefined references with static library
提问by Pyjong
I'm trying to make a static library from a class but when trying to use it, I always get errors with undefined references on anything. The way I proceeded was creating the object file like
我正在尝试从一个类中创建一个静态库,但是在尝试使用它时,我总是遇到任何未定义引用的错误。我进行的方式是创建目标文件,如
g++ -c myClass.cpp -o myClass.o
and then packing it with
然后打包
ar rcs myClass.lib myClass.o
There is something I'm obviously missing generally with this. I bet it's something with symbols. Thanks for any advice, I know it's most probably something I could find out if reading some tutorial so sorry if bothering with stupid stuff again :)
对此,我显然普遍缺少一些东西。我敢打赌这是带有符号的东西。感谢您的任何建议,我知道这很可能是我在阅读一些教程后可以找到的东西,如果再次打扰愚蠢的东西,我很抱歉:)
edit:
编辑:
myClass.h:
我的类.h:
class myClass{
public:
myClass();
void function();
};
myClass.cpp:
我的类.cpp:
#include "myClass.h"
myClass::myClass(){}
void myClass::function(){}
program using the class:
使用该类的程序:
#include "myClass.h"
int main(){
myClass mc;
mc.function();
return 0;
}
finally I compile it like this:
最后我像这样编译它:
g++ -o main.exe -L. -l myClass main.cpp
the error is just classic:
错误只是经典:
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
回答by mch
This is probablya link order problem. When the GNU linker sees a library, it discards all symbols that it doesn't need. In this case, your library appears before your .cpp file, so the library is being discarded before the .cpp file is compiled. Do this:
这可能是链接顺序问题。当 GNU 链接器看到一个库时,它会丢弃所有不需要的符号。在这种情况下,您的库出现在 .cpp 文件之前,因此在编译 .cpp 文件之前会丢弃该库。做这个:
g++ -o main.exe main.cpp -L. -lmylib
or
或者
g++ -o main.exe main.cpp myClass.lib
The Microsoft linker doesn't consider the ordering of the libraries on the command line.
Microsoft 链接器不考虑命令行上库的顺序。
回答by tprk77
Another possible cause: forgetting extern "C"
.
另一个可能的原因:忘记extern "C"
.
I ran into this because I was trying to link a C++ program with a C static library. The library's header didn't have extern "C"
so the linker was looking for a mangled function name, and the library actually had the unmangled function name.
我遇到这个是因为我试图将 C++ 程序与 C 静态库链接起来。库的头文件没有,extern "C"
所以链接器正在寻找一个错位的函数名,而库实际上有一个未错位的函数名。
It took a while to figure out what was going on, so I hope this helps someone else.
花了一段时间才弄清楚发生了什么,所以我希望这对其他人有所帮助。
回答by Grzegorz Dymek
This is an issue how the linker optimizes the output code. Lets assume we have an executable that uses two libraries: Lib_Aand Lib_B. Lib_Adepends on Lib_BThe Lib_Adefines symbols: Lib_A1and Lib_A2, and the Lib_Bdefines symbol Lib_B1and Lib_B2. Now lets assume that the executable uses only symbol Lib_A1, and Lib_A1uses symbol Lib_B1which is defined in Lib_B. Symbol Lib_B1is never used in the executable.
这是链接器如何优化输出代码的问题。假设我们有一个使用两个库的可执行文件: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_B1这是在定义Lib_B。符号Lib_B1从未在可执行文件中使用。
- In case of windows, the linker works like this: I have executable with two which uses some libs and all symbols used in executable and all libs are lib_A1and lib_B1. Thus I will need these two symbols, and the rest is unnecessary. I will undefine lib_A2and lib_B2
- In case of linux if you link Lib_Bbefore Lib_Alike this:
g++ .... -lLib_B -lLib_A
The linker works like this: I have executable that first links Lib_B. I do not see that the executable uses symbol Lib_B1nor Lib_B2. They are unnecesary, thus I will undefine them. Later the linker see. Oh I have another library Lib_A. I can see that executable uses symbol Lib_B1. I will keep it and undefine unused symbol Lib_B2. It does not see that Lib_B1uses Lib_A1, Which is already undefined. - In case of linux if you link Lib_Abefore Lib_Blike this:
g++ ... -lLib_A -lLib_B
The linker works like this: I have executable that first links Lib_A. Oh, I can see that executable uses Lib_A1. I will keep them and undefine Lib_A2. Later it can see. Oh I have another library Lib_B. I can see that now executable with already linked symbols, uses Lib_B1, I will keep them. As a result it keeps Lib_B1and Lib_A1, and undefined Lib_B2and Lib_A2.
- 在 Windows 的情况下,链接器的工作方式如下:我有两个可执行文件,它们使用一些库和可执行文件中使用的所有符号,所有库都是lib_A1和lib_B1。因此我将需要这两个符号,其余的都是不必要的。我将取消定义lib_A2和lib_B2
- 在linux下的情况下,如果您链接Lib_B前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_A前Lib_B这样的:
g++ ... -lLib_A -lLib_B
链接器的工作原理是这样的:我有可执行第一链接Lib_A。哦,我可以看到可执行文件使用Lib_A1。我会保留它们并取消定义Lib_A2。后来就可以看到了。哦,我还有另一个图书馆Lib_B。我可以看到现在可以使用已经链接的符号执行,使用Lib_B1,我会保留它们。因此,它保留Lib_B1和Lib_A1,以及未定义的Lib_B2和Lib_A2。
回答by Grzegorz Dymek
Use:
用:
g++ -o main.exe main.cpp myClass.lib
Using the library path and the -l flag is fraught with problems, but if you must do it, rename your library to libmylib.a and then compile as:
使用库路径和 -l 标志充满问题,但如果必须这样做,请将库重命名为 libmylib.a,然后编译为:
g++ -o main.exe main.cpp -L. -lmylib
Note also that for portability reasons, it's generally a bad idea to use mixed case in the names of source or output files.
另请注意,出于可移植性的原因,在源文件或输出文件的名称中使用大小写混合通常是一个坏主意。
回答by Oshi
This should avoid linking errors and create the .so shared library:
这应该避免链接错误并创建 .so 共享库:
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true