Как компилятор использует файл lib? - PullRequest
4 голосов
/ 03 апреля 2010

Мне интересно, как компилятор c / c ++ анализирует файлы lib? Я имею в виду, что я создаю библиотеку, содержащую некоторые классы, я использую эту библиотеку в своей основной программе. Как компилятор узнает, какие имена классов есть в этой библиотеке? Конечно, эта информация присутствует в двоичном формате, я хочу использовать эту функцию в моей программе, а точнее, у меня есть двоичный файл lib, и я хочу знать все классы и свойства / функции, присутствующие в этом файле lib.

Возможно ли это? Если компилятор может сделать это, почему не может какая-то библиотека?

спасибо за любую подсказку

Ответы [ 4 ]

6 голосов
/ 03 апреля 2010

Компилятор не делает то, что вы предлагаете, но компоновщик делает.

Компилятору известна необходимая ему информация из заголовочных файлов, относящихся к файлам lib.

Затем компоновщик объединяет объявления, которые вы включаете, и файл lib вместе с другими объектными файлами.

Вероятно, можно получить информацию из файла .lib, например, декомпилировав его, но это большая работа и, вероятно, не то, что вы хотите сделать.

1 голос
/ 06 октября 2011

Как правило, библиотека .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

1 голос
/ 03 апреля 2010

В зависимости от вашей системы (я знаю, что это верно для .a файлов в Linux, не очень уверенно для Windows), библиотечные файлы - это просто архивный файл (то есть .a), содержащий кучу обычных объектных файлов. Подумайте смолу или молнию, и вы будете чертовски близко. Компоновщик более или менее просто извлекает файлы из архива, прикрепляет их в командной строке и связывает все вместе (на самом деле он этого не делает, потому что у него есть некоторые специальные правила, такие как только ленивость, но это достаточно близко для темы под рукой).

Если вы хотите узнать, что внутри, получите библиотечный инструмент (IIRC ar в Linux) и покопайтесь в документации. Даже деньги говорят, что инструмент сможет извлекать объектные файлы, и оттуда вы можете использовать стандартные инструменты для извлечения их содержимого.

0 голосов
/ 03 апреля 2010

Чтобы усилить ответ Брайана Р. Бонди к тому времени, когда код достиг компоновщика, самая полезная информация для людей была удалена. Например, вы можете извлечь следующую информацию из объектного файла (библиотеки):

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

Что действительно менее чем полезно. Документация библиотеки должна объяснить, почему вы хотите ее использовать и как; если библиотека не так задокументирована, возможно, вам нужна библиотека получше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...