Загрузка общей библиотеки по пути во время выполнения - PullRequest
23 голосов
/ 02 октября 2011

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

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

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

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

Ответы [ 4 ]

26 голосов
/ 02 октября 2011

В системах 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 ()Для получения дополнительной информации см. Справочную страницу dlopen (1).

10 голосов
/ 02 октября 2011

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

3 голосов
/ 02 октября 2011

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

1 голос
/ 02 октября 2011

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

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

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

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

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

...