Статическое и динамическое связывание одной и той же библиотеки в Linux - PullRequest
2 голосов
/ 06 июня 2011

У меня есть общий объект / исполняемый файл, который статически и динамически связан с одной и той же библиотекой.

Библиотека: liba.a и liba.so

liba.a , созданный с использованием: ar -rv liba.a a.o, содержит libprint () -> печатает "static5"

liba.so , созданный с использованием: gcc -shared -o liba.so -Wl, -h, liba.so a.o, содержит libprint () печатает «dynamic5», libprint2 () печатает "dynamic6"

Exe b , созданный связыванием как архива, так и общего объекта:

При связывании с GCC / Linux я обнаружил, что вызванная реализация ВСЕГДА из liba.a.

У меня есть функция libprint () , определенная в liba.so, liba.a, которая выводит другое значение. Из того, что я вижу, это основано на порядке ссылки:

gcc -o b b.o liba.a liba.so -lc ./b

static5 dynamic6

gcc -o b b.o liba.so liba.a -lc ./b

dynamic5 dynamic6

Зачем нам намеренно нужно ссылаться на .a и .so для одной и той же библиотеки?:

Как получить общий объект, который будет иметь преимущество перед архивом, кроме порядка ссылок? ( -dy / -Bdynamic , кажется, не имеет никакого эффекта?)

1. Если общий объект отсутствует, исполняемый файл завершается с ошибкой 2. Мы можем разместить любой фиктивный общий объект с тем же именем, просто чтобы удовлетворить dlopen () 3. Даже после загрузки общего объекта функция из архива называется

Обновление № 2 Вот проблема фактическая (как упоминалось в Статическое и динамическое связывание одной и той же библиотеки )

libd.so связан с общим объектом liba.so
ldd libd.so liba.so => ​​./liba.so

b связан с общим объектом libd.so и архивом liba.a .

gcc -o b b.o libd.so liba.a -lc лдд б libd.so => ​​./libd.so liba.so => ​​./liba.so

Теперь b , кажется, сначала вызывает функцию из архива, а затем разделяемый объект.

Таким образом, даже если мы обновим liba.so , эти изменения не будут отражены в b . Есть ли способ обойти это?

1 Ответ

1 голос
/ 06 июня 2011

Когда вы ставите .a первым, компоновщик находит в нем libprint() и связывает его, но не libprint2(). Он продолжает поиск в библиотеках, чтобы найти другую функцию, и находит ее в .so.

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

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

...