用于确定是否存在动态库的多平台方式

时间:2013-04-10 12:06:45

标签: c++ visual-c++ g++ dynamic-library

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

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

2 个答案:

答案 0 :(得分:4)

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

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

  1. 在给定文件名称的情况下加载库(例如“xx”,然后在体系结构特定代码中将其翻译为“xx.so”或“xx.dll”)。
  2. 根据索引(“函数编号1”)或名称(“函数blah”)查找函数,并返回地址。
  3. 对所有相关功能重复步骤2。
  4. 当不再需要库时,请使用提供的句柄将其关闭。
  5. 如果第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环境,你的应用程序就会崩溃。

答案 1 :(得分:1)

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

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