如何防止使用为不同版本编译的库

时间:2017-12-04 20:52:23

标签: c++ dll

是否有任何标准方法强制用户在编译期间使用的同一版本中完全使用我的dll库?

假设我在版本1.0中有一个带有函数的库:

extern "C" void A();

在版本1.1中,我添加了重大更改,例如:此函数的另一个参数,所以我有:

extern "C" void A(int);

dll中的导出名称完全相同,但如果开发人员使用1.1版编译产品,则将其发送给客户,客户将仅更新产品(exe文件),然后一切都将失败。并且它可能在运行时随机点失败(取决于执行此更改函数的时间)。

是否有任何标准方法可以防止以错误的版本加载库?我最感兴趣的是Windows dll文件的解决方案。 (但如果有其他平台特有的解决方案,请留下评论)

上面的例子很简单。添加c ++ mangling解决了上面的特殊问题,但我正在寻找更通用的解决方案。

我的想法是在库头文件中添加一个静态对象。构造函数中的这个静态对象可以从库执行方法,名称中的方法编码当前版本,如:init_library_1_1();因此,如果dll中缺少该方法,那么在最初用户看到出现问题。但解决方案看起来像一个肮脏的解决方法。我必须注意开发人员包含此文件。

对于这样的问题有没有更好的解决方案?

2 个答案:

答案 0 :(得分:0)

没有标准答案,但许多编译器/链接器对具有非标准功能来执行这些类型的测试。

例如,Visual C ++有" #pragma detect_mismatch"将记录放在输出对象文件中,然后在执行链接时测试记录,如果它们不匹配,则报告错误。如果DLL在运行时动态加载而不是在加载期间静态加载,我不相信这会有任何好处。我相信gcc / clang有类似的东西,但不知道细节。

答案 1 :(得分:0)

我能够做到的最佳解决方案:

在.dll文件中添加导出的功能:

extern "C"
{
    DLL_FUNCTION void library_dll_required_in_version_10_0_1() {}
}

在公共标题中添加:

namespace library_impl{

    extern "C"{
        DLL_FUNCTION void library_dll_required_in_version_10_0_1();
    }

    class VersionProtection{
    public:
        VersionProtection() {
            library_dll_required_in_version_10_0_1();
        }
    };
    static VersionProtection aversion_protection_verifier;
}

最后如果用户尝试使用错误版本的dll文件,那么他会在程序启动时收到很好的错误消息:

  

过程入口点library_dll_required_in_version_10_0_1   无法位于动态链接库

每次更改后都需要更新功能版本号。