我需要检查动态库是否存在,以便稍后可以安全地调用使用此库的函数。确定动态库是否存在的多平台方法
有没有多平台的方法来检查这个?我的目标是MS Windows 7(VC++ 11)和Linux(g ++)。
我需要检查动态库是否存在,以便稍后可以安全地调用使用此库的函数。确定动态库是否存在的多平台方法
有没有多平台的方法来检查这个?我的目标是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环境,你的应用程序将会崩溃。
请注意:我使用eg。 qt.lib中的Qt函数(假设存在这样的lib),并且这些函数本身加载一个DLL。如果它们失败,我的整个应用程序将失败所以我想通过在试图加载之前手动检查DLL是否存在来防止这种情况。你明白吗? – Parobay
是的,实现这一目标的唯一方法是不首先将'qt.lib'链接到您的应用程序中,然后使用您编写的代码来检查您是否可以加载'qt.dll',并且然后使用它。但是对于qt来说这将是一个非常糟糕的任务,因为它没有一个简单的界面。这是一大堆功能。而qt的全部重点是使代码可移植并在多个平台上编译相同。这将是一个更好的选择,建立一个安装程序,检查是否和/或确保安装qt'会导致应用程序的安装。 –
我要说的是,如果你使用'qt.lib'链接,系统加载器将在应用程序启动时自动加载'qt.dll'或'qt.so' - 如果共享库不是在那里,它会使可执行文件的负载失效。这是可执行程序及其组成共享库如何在正常系统中加载的一部分。你不能改变它,除非你停止使用'qt.lib',这又意味着你不能只在代码中使用Qt函数。您必须通过一个接口来调用它们,以检查它们是否可用,如果不可用,则执行其他操作。 –
LoadLibrary调用应该失败,那么你可以知道动态库是否存在。还有动态加载,你会从动态库中获得函数指针,如果指针为空,那么平台不支持该平台上的那个函数。
在windows上您有LoadLibrary
API来加载动态库。和GetProcAddress
API在该lib中查找所需的函数。如果GetProcAddress
针对您正在查找的特定功能返回NULL,则该平台不存在该功能。您可以记录然后决定回退。
LoadLibrary调用应该失败,那么你可以知道。另外动态加载你从dll得到函数指针,如果指针为空,那么平台不支持那个平台上的那个函数。问题是什么? –
如果库无法加载,那么我的应用程序崩溃 - 我想避免这种情况。这种情况是我使用了一些库(静态链接),期望它们的运行时助手动态库。 – Parobay
对于POSIX变体(如Linux和Mac OSX),请查找['dlopen'](http://pubs.opengroup.org/onlinepubs/009695399/functions/dlopen.html)和['dlsym'](http:// pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html)。没有我知道的跨平台库,但它很简单,您可以使用非常类似的代码来检查Windows和Linux(相同的布局,只是不同的功能)。 –