6

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

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

4

2 回答 2

4

要动态“使用”共享库中的函数,需要该库不是可执行文件的一部分,因此您需要编写代码来加载该库,然后使用该函数。很可能有办法以可移植的方式做到这一点,但我不知道有任何代码可以做到这一点。

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

  1. 加载给定文件名的库(例如“xx”,然后在体系结构特定代码中将其转换为“xx.so”或“xx.dll”)。
  2. 根据索引(“函数编号 1”)或名称(“函数 blah”)查找函数,并返回地址。
  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;
 }

如您所见,代码突然变得更加“混乱”。没关系你必须跳过什么箍才能找到 a 的构造函数QObject,或者更糟的是,从 a 继承QObject。换句话说,如果您在代码中使用 Qt,您可能会被直接链接到“qt.lib”所困,如果计算机上未安装 Qt 环境,您的应用程序将崩溃。

于 2013-04-10T12:17:22.003 回答
1

LoadLibrary 调用应该失败,然后您可以知道动态库是否存在。同样通过动态加载,您可以从动态库中获取函数指针,如果指针为空,则平台不支持该平台上的该函数。

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

于 2013-04-10T12:16:32.930 回答