繁体   English   中英

确定动态库是否存在的多平台方法

[英]Multiplatform way to determine if a dynamic library is present

我需要检查是否存在动态库,以便以后可以安全地调用使用该库的函数。

有没有多平台的方式来检查这一点? 我的目标是MS Windows 7(VC ++ 11)和Linux(g ++)。

要动态地“使用”共享库中的函数,要求该库不是可执行文件的一部分,因此您需要编写代码以加载该库,然后使用该函数。 可能有许多方法可以以可移植的方式完成此操作,但是我不知道有任何代码可以执行此操作。

编写代码不是很困难。 作为“步骤”,它涉及以下内容:

  1. 加载具有给定文件名的库(例如“ xx”,然后在特定于体系结构的代码中将其翻译为“ xx.so”或“ xx.dll”)。
  2. 根据索引(“功能编号1”)或名称(“功能无效”)查找功能,然后返回地址。
  3. 对所有相关功能重复步骤2。
  4. 当不再需要该库时,请使用提供的手柄将其关闭。

如果第1步失败,则您的库不存在(或否则“不起作用”),因此您无法在其中调用函数...

显然,有很多方法可以设计提供此类功能的界面,而具体的实现方式将取决于实际的问题设置。

编辑:

为了阐明直接使用DLL与使用动态加载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调用应该失败,然后您可以知道动态库是否存在。 同样,通过动态加载,您可以从动态库中获得函数指针,如果指针为null,则平台在该平台上不支持该函数。

在Windows上,您具有LoadLibrary API来加载动态库。 然后使用GetProcAddress API在该库中查找所需的功能。 如果GetProcAddress为该特定功能返回NULL,则说明您正在寻找该功能不存在于该平台。 您可以先登录然后决定退路。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM