Цель использования динамического загрузчика динамиков c вместо прямого вызова функции? - PullRequest
0 голосов
/ 14 января 2020

Сегодня я столкнулся с чем-то похожим на этот фрагмент кода.

В A.h:

class A { blah blah blah }

#define CREATE_A_FUNC_NAME   ("CreateA")
extern "C" A* CreateA(void);
typedef A* (*funcCreateA)(void);

В main.cpp:

void* handle = dlopen("libA.so", RTLD_LAZY);
funcCreateA func = (funcCreateA)dlsym(handle, CREATE_A_FUNC_NAME);
A* a = func();

Теперь очевидно, что Ah - это только заголовок для объявлений, и все его реализации хранятся в libA.so.

Я проверил, что если я правильно настроил свой проект, то есть библиотека правильно связана, я могу просто сделать A* a = CreateA() чтобы получить указатель на вновь созданный экземпляр A. Отсюда и возникают вопросы. Почему go столько хлопот, чтобы достичь чего-то простого, как один вызов функции? Как называется эта технология или техника? Каковы плюсы и минусы? Когда я должен использовать эту технику? Спасибо!

1 Ответ

3 голосов
/ 14 января 2020

Основные причины использовать dlsym вместо прямой связи с DSO:

  • вы хотите добавить в приложение механизм плагинов, поэтому вам нужно иметь возможность загружать DSO на лету (плагины не известны компоновщику при сборке exe) . Самый простой подход для этого - добавить некоторый виртуальный базовый класс (я предполагаю, что у 'A' есть несколько виртуальных методов?) , а затем экспортировать метод создателя с помощью связи C ( который отключает искажение имени в C ++) . Выглядит так, как будто это и есть цель?
  • Возможно, вы оптимизировали код для определенного c набора команд ЦП (т. Е. При запуске игрового движка проверьте, какая команда является последней, установленной для ЦП поддерживает, загружает соответствующую библиотеку SSE или AVX во время выполнения, а затем вызывает методы, оптимизированные для этого конкретного ЦП) .
  • В редких случаях вам может понадобиться «выгрузить» некоторый тяжелый код, чтобы освободить больше памяти на устройстве. Это часто случается на Android / iOS и консолях (например, выпуск компилятора шейдеров после компиляции всех шейдеров) .

Стоит отметить, что если вы подключитесь к DSO напрямую, под капотом, компоновщик просто вставит код dlsym / dlopen при запуске приложения, который автоматически загрузит DSO и разрешит символы.

...