я могу иметь приложение, которое dlopen в этом разделяемой библиотеки, dlsym() sym1 и вызывать его. Возможно ли для приложения использовать dlopen() какую-либо другую разделяемую библиотеку с sym1 как неопределенную и она будет разрешена для sym1 в lib_imp1.so?
Да: если первый dlopen
использует RTLD_GLOBAL
, затем вводятся в глобальную область видимости все символы, экспортируемые из lib_imp1.so
(включая sym1
), и становятся видимыми для других библиотек, загруженных позже.
Если возможно, то у нас могут быть две реализации lib_imp1.so и lib_imp2.so с двумя разными адресами для одного символа sym1.
Да. Это не рекомендуется.
Если приложение загружает другую разделяемую библиотеку с неразрешенным символом sym1, можем ли мы иметь какой-либо элемент управления, на котором sym1 (lib_imp1.so или lib_imp2.so) разрешается?
No. Предполагая, что вы dlopen
ред как lib_imp1.so
и lib_imp2.so
с RTLD_GLOBAL
, любая последующая библиотека всегда будет связываться с sym1
из первой dlopen
библиотеки эд, что обеспечивает его (т.е. он будет решать lib_imp1.so
определению).
Далее, если lib_imp1.so
также экспортирует sym2
, и ничего в lib_imp2.so
вызовов sym2
, этот символ будет также решительность к определению внутри lib_imp1.so
(если вы не проявлять особую осторожность и использовать -Bsymbolic
).
В результате библиотеки UNIX .so
ведут себя так же, как архивные библиотеки, а не как окна DLL
. Это делает наличие двух отдельных реализаций, которые экспортируют один и тот же интерфейс в значительной степени неработоспособным в одном процессе.
При генерации lib_imp1.so мы можем сказать, что, хотя мы хотим экспортировать sym1, мы не хотим, чтобы с ним был разрешен какой-либо неразрешенный символ?
dlsym
использует точно тот же процесс разрешения. Если вы сделаете символ недоступным для чего-либо, чтобы разрешить его, dlsym
не найдет его. И наоборот, символ экспорта означает «сделать его доступным для разрешения» (либо dlopen
, либо просто регулярное нерешенное разрешение зависимостей).