Загрузка разделяемой библиотеки по пути во время выполнения

Я строю Java-приложение, которое использует разделяемую библиотеку, написанную на C++ и скомпилированную для разных операционных систем. Проблема в том, что эта общая библиотека сама зависит от дополнительной библиотеки, которую обычно находит в соответствующей переменной среды (PATH, LIBRARY_PATH или же LD_LIBRARY_PATH).

Я могу - но не хочу - устанавливать эти переменные среды. Я бы предпочел загрузить необходимые разделяемые библиотеки по заданному пути во время выполнения - как плагин. И нет - я не хочу никаких стартовых приложений, которые запускают новый процесс в новой среде. Кто-нибудь знает, как этого добиться?

Я знаю, что это должно быть возможно, так как одна из используемых мной библиотек способна загружать свои плагины по заданному пути. Конечно, я бы предпочел независимый от платформы код, но если это невозможно, отдельные решения для Windows, Linux и MacOS также сделали бы это.

РЕДАКТИРОВАТЬ Я должен был упомянуть, что разделяемая библиотека, которую я хотел бы использовать, является объектно-ориентированной, что означает, что привязка отдельных функций этого не сделает.

4 ответа

Un UNIX/Linux системы, которые вы можете использовать dlopen, Проблема в том, что вам нужно получить все необходимые символы через dlsym

Простой пример:

typedef int (*some_func)(char *param);

void *myso = dlopen("/path/to/my.so", RTLD_NOW);
some_func *func = dlsym(myso, "function_name_to_fetch");
func("foo");
dlclose(myso);

Загрузит.so и выполнит там функцию function_name_to_fetch(). Смотрите man-страницу dlopen(1) для более подробной информации.

В Windows вы можете использовать LoadLibraryи в Linux, dlopen, API чрезвычайно похожи и могут напрямую загружать so/dll, предоставляя полный путь. Это работает, если это зависимость во время выполнения (после загрузки вы "связываете", вызывая GetProcAddress/dlsym.)

Я согласен с другими постерами об использовании dlopen и LoadLibrary. Libltdl предоставляет вам независимый от платформы интерфейс для этих функций.

Я не думаю, что вы можете сделать это для этого.

Большинство Dll имеют своего рода функцию init(), которая должна вызываться после загрузки, и иногда функции init() требуются некоторые параметры, и она возвращает некоторый дескриптор, который будет использоваться для вызова функций dll. Знаете ли вы определение дополнительной библиотеки?

Тогда первая библиотека не может просто посмотреть, находится ли DLL X в ОЗУ только по ее имени. Он может находиться в другом каталоге или в другой сборке / версии. ОС распознает библиотеку, если полный путь совпадает с уже загруженной, и предоставит доступ к ней, а не загрузит ее второй раз.

Другая библиотека может загружать свои плагины из другого пути, потому что она написана так, чтобы не зависеть от PATH, и они являются его собственными плагинами.

Вы пытаетесь обновить переменные среды процесса из кода перед загрузкой Dll? Это не зависит от начального процесса.

Другие вопросы по тегам