в gcc, как вызвать разрешение символа во времени выполнения

Мое первое сообщение на этом сайте с огромной надеждой:: Я пытаюсь понять, что статическое подключение, динамическое подключение, совместно использовало библиотеки, статические библиотеки и т.д., с gcc. Каждый раз я пытаюсь копаться в этой теме, у меня есть что-то, что я не вполне понимаю.

Некоторая практическая работа:

bash$ cat main.c

#include "printhello.h"
#include "printbye.h"

void main()
{
PrintHello();
PrintBye();
}

bash$ cat printhello.h
void PrintHello();

bash$ cat printbye.h
void PrintBye();

bash$ cat printbye.c
#include <stdio.h>

void PrintBye()
{
printf("Bye bye\n");
}

bash$ cat printhello.c
#include <stdio.h>

void PrintHello()
{
printf("Hello World\n");
}

gcc -Wall -fPIC -c *.c -I.
gcc -shared -Wl,-soname,libcgreet.so.1 -o libcgreet.so.1.0   *.o
ln -sf libcgreet.so.1.0 libcgreet.so
ln -sf libcgreet.so.1.0 libcgreet.so.1

Таким образом, я создал общую библиотеку. Теперь я хочу связать эту общую библиотеку со своей основной программой для создания исполняемого файла.

gcc -Wall -L. main.c -lcgreet -o greet

Это очень хорошо работает и если я установил LD_LIBRARY_PATH, прежде чем выполнение приветствует (или свяжите его с rpath опцией), я могу заставить его работать.

Мой вопрос однако отличается: Так как я так или иначе пользуюсь совместно использованной библиотекой, это не возможный вызвать разрешение символа во времени выполнения (не уверенный в терминологии, но возможно названный динамическим подключением согласно книге "Компоновщики и Загрузчики"). Я понимаю, что мы не можем хотеть делать это, потому что это делает прогон программы медленным и имеет наверху каждый раз, мы хотим запустить программу, но я пытаюсь понять это для очистки моих понятий.

Компоновщик gcc предоставляет какую-либо возможность задерживать разрешение символа во времени выполнения? (чтобы сделать это с библиотекой, мы на самом деле собираемся запустить программу с) (поскольку библиотека, доступная во время компиляции, может отличаться, чем одно доступное во времени выполнения, если любые изменения в библиотеке), я хочу смочь сделать sth как:

bash$ gcc main.c-I.

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

Спасибо, ученик навсегда.

5
задан xyz 1 July 2010 в 13:08
поделиться

1 ответ

Любой компоновщик (gcc, ld или любой другой) разрешает ссылки только во время компиляции. Это потому, что стандарт ELF (как и большинство других) не определяет компоновку "во время выполнения", как вы описываете. Они либо компонуются статически (т.е. lib.a), либо во время запуска (lib.so, который должен присутствовать при загрузке ELF). Однако, если вы используете динамическую связь, компоновщик только помещает в ELF имя файла и символы, которые он должен найти, но не компонует файл напрямую. Таким образом, если вы захотите обновить библиотеку до более новой версии, вы сможете это сделать, если только система сможет найти то же имя файла (путь может быть другим) и те же имена символов.

Другой вариант получения символов во время выполнения - использовать dlopen, который не имеет ничего общего с gcc или ld. dlopen, проще говоря, открывает библиотеку динамических ссылок, точно так же, как это делает fopen, и возвращает вам хэндл, который вы передаете в dlsym с именем нужного вам символа, который может быть, например, именем функции. dlsym передаст вам указатель на этот символ, который вы можете использовать для вызова функции или в качестве переменной. Именно так реализуются плагины.

10
ответ дан 13 December 2019 в 19:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: