Мне нужно проверить, присутствует ли динамическая библиотека, чтобы позже я мог безопасно вызывать функции, которые используют эту библиотеку.
Есть ли мультиплатформенный способ проверить это? Я ориентируюсь на MS Windows 7 (VC ++ 11) и Linux (g ++).
Чтобы динамически «использовать» функцию из разделяемой библиотеки, необходимо, чтобы библиотека не была частью исполняемого файла, поэтому вам нужно будет написать код для загрузки библиотеки и затем использовать функцию. Вполне могут быть способы сделать это портативным способом, но я не знаю ни одного кода, доступного для этого.
Это не очень сложный код для написания. В качестве «шагов» подразумевается следующее:
Если шаг 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.
Вызовы LoadLibrary должны потерпеть неудачу, тогда вы можете узнать, присутствует динамическая библиотека или нет. Также при динамической загрузке вы получаете указатель на функцию из динамической библиотеки, и если указатель равен нулю, то платформа не поддерживает эту функцию на этой платформе.
На окнах у вас есть LoadLibrary
API для загрузки динамической библиотеки. А также GetProcAddress
API для поиска нужной функции в этой библиотеке. Если GetProcAddress
возвращает NULL для той конкретной функции, которую вы ищете, что функциональность отсутствует для этой платформы. Тогда вы можете войти в систему и принять решение об отказе.