Многоплатформенный способ определения наличия динамической библиотеки

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

Есть ли мультиплатформенный способ проверить это? Я ориентируюсь на MS Windows 7 (VC ++ 11) и Linux (g ++).

4

Решение

Чтобы динамически «использовать» функцию из разделяемой библиотеки, необходимо, чтобы библиотека не была частью исполняемого файла, поэтому вам нужно будет написать код для загрузки библиотеки и затем использовать функцию. Вполне могут быть способы сделать это портативным способом, но я не знаю ни одного кода, доступного для этого.

Это не очень сложный код для написания. В качестве «шагов» подразумевается следующее:

  1. Загрузите библиотеку с указанным именем файла (например, «xx», который затем переводится в «xx.so» или «xx.dll» в коде, специфичном для архитектуры).
  2. Найдите функцию на основе индекса («функция номер 1») или имени («функция бла») и верните адрес.
  3. Повторите шаг 2 для всех соответствующих функций.
  4. Когда библиотека больше не нужна, закройте ее с помощью предоставленной ручки.

Если шаг 1 не пройден, то ваша библиотека отсутствует (или иначе «не будет работать»), поэтому вы не можете вызывать функции в ней …

Понятно, что существует множество способов разработать интерфейс для обеспечения функциональности такого типа, и то, как именно вы это сделаете, будет зависеть от того, какова ваша реальная проблема.

Редактировать:

Чтобы прояснить разницу между использованием DLL напрямую и использованием динамической загрузки из кода:

Представьте, что это наш «shared.h», который определяет функции для разделяемой библиотеки.
(Есть, вероятно, некоторые declspec(...) или же exportsymbol или другие подобные вещи в реальном заголовке, но я пока полностью проигнорирую это).

 int func1();
char *func2(int x);

В фрагменте кода, который напрямую использует DLL, вы просто должны сделать:

 #include <shared.h>

int main()
{
int x = func1();
char *str = func2(42);

cout << "x=" << x << " str=" << str << endl;
return 0;
}

Довольно прямо, верно?

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

 #include <shared.h>

typedef int (*ptrfunc1)();
typedef char * (*ptrfunc2)(int x);

int main()
{
SOMETYPE handle = loadlibrary("shared");
if (handle == ERROR_INDICATOR)
{
cerr << "Error: Couldn't load shared library 'shared'";
return 1;
}
ptrfunc1 pf1 = reinterpret_cast<ptrfunc1>(findfunc("func1"));
ptrfunc2 pf2 = reinterpret_cast<ptrfunc2>(findfunc("func2"));

int x = pf1();
char *str = pf2(42);

cout << "x=" << x << " str=" << str << endl;
return 0;
}

Как видите, код неожиданно стал намного более «грязным». Не берите в голову, через какие обручи вы должны прыгнуть, чтобы найти конструктор для QObjectили, что еще хуже, наследовать от QObject, Другими словами, если вы используете Qt в своем коде, вы, вероятно, застряли с прямой ссылкой на «qt.lib», и ваше приложение вылетит, если на компьютере не установлена ​​среда Qt.

4

Другие решения

Вызовы LoadLibrary должны потерпеть неудачу, тогда вы можете узнать, присутствует динамическая библиотека или нет. Также при динамической загрузке вы получаете указатель на функцию из динамической библиотеки, и если указатель равен нулю, то платформа не поддерживает эту функцию на этой платформе.

На окнах у вас есть LoadLibrary API для загрузки динамической библиотеки. А также GetProcAddress API для поиска нужной функции в этой библиотеке. Если GetProcAddress возвращает NULL для той конкретной функции, которую вы ищете, что функциональность отсутствует для этой платформы. Тогда вы можете войти в систему и принять решение об отказе.

1

По вопросам рекламы [email protected]