编译器如何使用lib文件?

时间:2010-04-03 05:31:38

标签: c++ c compiler-construction

我很好奇c / c ++编译器如何分析lib文件?我的意思是说我创建了一个包含一些类的库,我在我的主程序中使用该库。编译器如何知道该库中有哪些类名。当然这些信息以二进制格式存在,我想在我的程序中使用该功能,具体来说我有一个二进制lib文件,我想知道该lib文件中存在的所有类和属性/函数。

有可能吗?如果编译器可以做到那个为什么不能有些库?

感谢任何线索

4 个答案:

答案 0 :(得分:6)

编译器不会按照您的建议执行操作,但链接器会执行此操作。

编译器从与lib文件相关的头文件中了解所需的信息。

然后,链接器将您包含的声明和lib文件及其他目标文件放在一起。

例如,可能通过反编译从.lib文件获取信息,但这是很多工作,可能不是你想做的事情。

答案 1 :(得分:1)

取决于您的系统(我知道这对于Linux上的.a文件是正确的,对Windows不太确定)库文件只是一个包含一堆正常的归档文件(因此.a)目标文件。想想焦油或拉链,你就会非常接近。链接器或多或少只是从存档中提取文件,在命令行中添加它们并将所有内容链接在一起(它实际上并没有这样做,因为它有一些特殊的规则,比如只是懒得去,但它足够接近主题在手边)。

如果你想知道里面有什么,可以在Linux上获取库工具(IIRC ar)并深入研究文档。甚至金钱说该工具将能够提取目标文件,并从那里你可以使用标准工具来提取其内容。

答案 2 :(得分:1)

通常,.a库只是一个存档,它本身包含一堆目标文件。这些命令在Linux上完成,它将在不同平台之间变化。您通常可以通过运行nm libxxx.a

来检查存档的基本内容
/usr/lib> nm libc.a | head -10
init-first.o:
         U abort
         U _dl_non_dynamic_init
0000000000000000 T _dl_start
         w _dl_starting_up
         U __environ
         U __fpu_control
         U __init_misc
0000000000000004 C __libc_argc

nm联机帮助页有很多关于输出含义的详细信息。

ar命令可以为您提取单个文件,例如

~/tmp> ar x libc.a init-first.o
~/tmp> file init-first.o
init-first.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

正如您在上面所看到的,这里的对象是ELF格式,因此对于您所询问的复杂内容,您真正需要的是能够检查ELF二进制文件的内容。 Linux通常附带命令readelf,它将在命令行中提供大量信息:

~/tmp> readelf -s init-first.o
Symbol table '.symtab' contains 19 entries:
Num:    Value  Size Type    Bind   Vis      Ndx Name
 0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
 1: 00000000     0 SECTION LOCAL  DEFAULT    1
 2: 00000000     0 SECTION LOCAL  DEFAULT    3
 3: 00000000     0 SECTION LOCAL  DEFAULT    4
 4: 00000000     0 SECTION LOCAL  DEFAULT    5
 5: 00000000     0 SECTION LOCAL  DEFAULT    6
 6: 00000000    11 FUNC    GLOBAL DEFAULT    1 _dl_start
 7: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND abort
 8: 00000010   133 FUNC    GLOBAL DEFAULT    1 __libc_init_first
 9: 00000000     0 NOTYPE  WEAK   DEFAULT  UND _dl_starting_up
...

有一个库libelf很可能会执行您想要的操作并以编程方式访问此信息。我从来没有使用它,因为我总是从命令行工具中获得所需的信息。

http://directory.fsf.org/wiki/Libelf

答案 3 :(得分:0)

要在代码到达链接器时放大Brian R. Bondy's answer,人类最有用的信息已被删除。例如,您可以从目标文件(库)中提取以下信息:

class SomeClass implements SomeInterface {
    int get(class &otherClass c, float x);
    bool reallyCoolMethod(int x);
    ...
}

这真的不太有帮助。图书馆文档应该解释为什么要使用它以及如何使用它;如果图书馆没有这么记录,你可能想要一个更好的图书馆。