类似于运行时的预处理器

时间:2015-08-24 20:45:06

标签: c++ linker shared-libraries

在我的应用程序中,我使用库x2.0中的新函数,这在x1.0版本中找不到,但我想保持向后兼容性。

我是动态链接到那个库,当我在执行新函数之前使用简单的if条件来检查库版本时,它在启动时没有工作,exe搜索并解析所有函数,就像我正在运行链接到旧版本的应用程序给了我错误。

在运行时我想要对lib版本执行exe检查并执行新函数,或者根据该版本不执行它。

这是可能的,如果是的话,

我能做些什么来实现这个目标?

2 个答案:

答案 0 :(得分:1)

我认为最好的答案是对同一个dll使用隐式和显式链接 默认情况下,loader将加载dll,然后在代码中使用LoadLibrary和GetProcAddress,用于旧版本库中不存在的API

  HINSTANCE hinstLib; //Handle to the DLL
    // MYPROC ProcAddress; //Pointer to the function

   hinstLib = LoadLibrary("x.dll");
   FOO3 myFunc = (FOO3) GetProcAddress(hinstLib, "foo3");

答案 1 :(得分:0)

处理与第三方库的向后兼容性的一种方法是在其周围创建包装库/源文件,并确保您的应用程序永远不会从任何其他地方调用第三方库的任何功能。 / p>

假设您依赖于提供两个头文件“foo.h”和“bar.h”的第三方库。在库的版本1中,文件可能如下所示:

foo.h中:

void foo1();
int foo2();

bar.h:

void bar1(int);
int bar2(int);

让我们说,他们扩展了版本2中的界面,现在它们看起来像:

foo.h中:

void foo1();
int foo2();
double foo3();

bar.h:

void bar1(int);
int bar2(int);
int bar3(double);

在您的应用程序中,您希望能够在链接到库的第2版时使用foo3()bar3()但是您希望能够在版本中优雅地处理缺少这些功能的问题图书馆的一个。

您可以使用以下内容来完成此操作。

为库创建一个包装器.h文件。

foo_bar_wrapper.h:

namespace foo_bar_wrapper
{
    void foo1();
    int foo2();
    double foo3();
    void bar1(int);
    int bar2(int);
    int bar3(double);
}

然后,将它们实现为传递给第三方库。

foo_bar_wrapper.h:

#include "foo.h"
#include "bar.h"

namespace foo_bar_wrapper
{
    void foo1() { ::foo1(); }
    int foo2() { return ::foo2(); }
    double foo3() { return ::foo3(); }
    void bar1(int x) { return ::bar1(x); }
    int bar2(int x) { return ::bar2(x); }
    int bar3(double x) { return ::bar3(x); }
}

但是,由于库的版本1不支持foo3bar3,您可以使用:

namespace foo_bar_wrapper
{
    void foo1() { ::foo1(); }
    int foo2() { return ::foo2(); }

    double foo3() 
    {
#if FOO_LIBRARY_VERSION > 1
        return ::foo3();
#else
        // Deal gracefully with version 1
#endif
    }

    void bar1(int x) { return ::bar1(x); }
    int bar2(int x) { return ::bar2(x); }

    int bar3(double x)
    {
#if FOO_LIBRARY_VERSION > 1
       return ::bar3(x);
#else
        // Deal gracefully with version 1
#endif
    }

}

确保在构建应用程序时正确定义FOO_LIBRARY_VERSION