Как я изменяю библиотеку, от которой загружается функция в течение времени выполнения?
Например, скажите, что я хочу заменить стандарт printf
функция с чем-то новым, я могу записать свою собственную версию и скомпилировать его в общую библиотеку, затем поместить "LD_PRELOAD =/my/library.so" в среду прежде, чем выполнить мой исполняемый файл.
Но скажем, что вместо этого, я хочу изменить ту связь из самой программы. Конечно, это должно быть возможно... правильно?
Править
И не, следующее не работает (но если можно сказать мне, как ЗАСТАВИТЬ его работать, затем это было бы достаточно).
void* mylib = dlopen("/path/to/library.so",RTLD_NOW);
printf = dlsym(mylib,"printf");
AFAIK, это невозможно. Общее правило таково: если один и тот же символ встречается в двух библиотеках, ld.so отдаст предпочтение той библиотеке, которая была загружена первой. LD_PRELOAD работает, проверяя, что указанные библиотеки загружены до любых неявно загруженных библиотек.
Поэтому после начала выполнения все неявно загруженные библиотеки будут загружены, и поэтому уже слишком поздно загружать вашу библиотеку до них.
Вы не можете изменить это. В общем случае *NIX концепция связывания (или скорее отсутствие концепции) символ выбирается из первого объекта, где он встречается. (За исключением странной AIX, которая по умолчанию работает как OS/2.)
Программно вы всегда можете попробовать dlsym(RTLD_DEFAULT)
и dlsym(RTLD_NEXT)
. man dlsym
для получения дополнительной информации. Хотя это быстро выходит из-под контроля. Почему редко используется.
есть переменная окружения LD_LIBRARY_PATH, в которой компоновщик ищет библиотеки shred, добавьте свой путь в LD_LIBRARY_PATH, надеюсь, это сработает
Следует сказать, что попытка замены функций из библиотеки libc в вашем приложении ведет к неопределенному поведению согласно ISO C / POSIX, независимо от того, делаете ли вы это статически или динамически. Он может работать (и в основном будет работать в GNU / Linux), но неразумно полагаться на его работу. Если вы просто хотите использовать имя «printf», но сделать что-то нестандартное в вашей программе, лучший способ сделать это - #undef printf
и #define printf my_printf
ПОСЛЕ включая любые системные заголовки. Таким образом, вы не мешаете внутреннему использованию функции библиотеками, которые вы используете ... и ваша реализация my_printf может даже вызывать системный printf, если / когда это необходимо.
С другой стороны, если ваша цель - помешать работе библиотек, где-то в будущем вы, вероятно, столкнетесь с проблемами совместимости. Лучшим подходом, вероятно, было бы выяснить, почему библиотека не будет делать то, что вы хотите, без переопределения функций, которые она использует, исправления ее и отправки исправлений вверх по течению, если они уместны.
Сохраните результат dlsym () в таблице поиска (массив, хеш-таблица и т. Д.). Затем #undef print
и #define print
, чтобы использовать вашу версию таблицы поиска.