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

C++ 确定是否存在动态库的多平台方法,c++,visual-c++,g++,dynamic-library,C++,Visual C++,G++,Dynamic Library,我需要检查是否存在动态库,以便以后可以安全地调用使用该库的函数 有没有多平台的方法来检查这个?我的目标是MS Windows 7(VC++11)和Linux(g++)。LoadLibrary调用应该失败,然后您可以知道动态库是否存在。另外,通过动态加载,您可以从动态库获取函数指针,如果指针为null,则平台不支持该平台上的函数 在windows上,您有LoadLibraryAPI来加载动态库。和GetProcAddressAPI来查找该库中所需的函数。如果GetProcAddress为您正在查找

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


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

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

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

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

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

  • 加载给定文件名的库(例如“xx”,然后在特定于体系结构的代码中将其转换为“xx.so”或“xx.dll”)
  • 根据索引(“函数编号1”)或名称(“函数blah”)查找函数,并返回地址
  • 对所有相关功能重复步骤2
  • 当不再需要库时,请使用提供的手柄将其关闭 如果步骤1失败,那么您的库不存在(或者“无法工作”),因此您无法调用其中的函数

    显然,有很多方法可以设计一个接口来提供这种类型的功能,而具体的方法取决于实际的问题设置

    编辑:

    要澄清直接使用DLL与使用代码动态加载DLL之间的区别,请执行以下操作:

    假设这是我们的“shared.h”,它定义了共享库的函数 (在一个真正的标题中可能有一些
    declspec(…)
    exportsymbol
    或其他类似的东西,但我现在将完全忽略)

    在一段直接使用DLL的代码中,您只需执行以下操作:

     #include <shared.h>
    
     int main()
     {
         int x = func1();
         char *str = func2(42);
    
         cout << "x=" << x << " str=" << str << endl;
         return 0;
     }
    
    #包括
    int main()
    {
    int x=func1();
    char*str=func2(42);
    
    cout LoadLibrary调用应该失败,然后您就可以知道了。动态加载时,您也会从dll获取函数指针,如果指针为空,则平台不支持该平台上的函数。问题是什么?如果库无法加载,则我的应用程序崩溃-我希望避免这种情况。我使用了一些库(静态链接)需要运行时助手dynamic-libaries。对于POSIX变体(如Linux和Mac OSX),请查找和。据我所知,没有跨平台库,但它很简单,您可以使用非常相似的代码来检查Windows和Linux(相同的布局,只是真正不同的功能)@JoachimPileborg您所写的正是我需要的!您能在回答中描述一下吗?请注意:我使用Qt.lib中的例如Qt函数(假设存在这样的库),这些函数本身会加载一个DLL。如果它们失败,我的整个应用程序都会失败。因此,我想通过在它们尝试加载DLL之前手动检查DLL是否存在来防止出现这种情况。您明白吗?是的,实现这一点的唯一方法是首先不要将
    qt.lib
    链接到您的应用程序,然后使用您编写的代码n检查您是否可以加载
    qt.dll
    ,然后使用它。但是对于qt来说,这将是一项非常棘手的任务,因为它没有一个简单的接口。它有一大堆函数。qt的全部目的是使代码可移植,并在多个平台上编译相同的代码。构建一个检查的安装程序将是一个更好的选择s如果和/或确保在安装应用程序时安装了
    qt
    。我想说的是,如果您确实链接了
    qt.lib
    ,系统加载程序将自动尝试加载
    qt.dll
    qt。因此,当应用程序启动时-
    ,如果共享库不存在,它将无法加载可执行文件。这是可执行文件及其组成的共享库在正常系统中加载方式的一部分。除非您停止使用
    qt.lib
    ,否则您无法更改它,这意味着您不能仅在代码中使用qt函数。您必须通过检查它们是否可用的接口调用它们,如果没有,则会做其他事情。你确定吗?如果我链接到
    qt.lib
    ,并且不使用其中声明的任何函数,那么将发生
    qt.dll
    的神奇加载?为什么,有关需求的信息从何而来..动态库是动态的,因为它们是在运行时加载的,那么为什么系统加载器会加载dll.Short:一般来说(所有的lib/dll都是这样的),或者只是展示了库/dll设计的一种可能性?是的,我100%肯定-虽然如果你不使用库中的任何函数,它可能不会被链接进来。但是,链接到一个不在可执行文件中使用的库有什么意义?我不是说“此时未调用”-因为DLL是在加载可执行文件时加载的[至少已初始化]。唯一不产生“库不存在时失败”效果的方法“是指没有一段代码直接引用qt.lib中的任何内容,然后通过
    LoadLibrary
    dlopen
    使用库以及相应的函数来查找每个函数。
     #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;
     }