我有一个导出C ++类的MFC扩展DLL,我需要修改类方法的行为。这些更改不会影响该类方法的签名。
我不想重新编译使用此库的先前发布版本的“lib”文件的模块。
如果更改修改了函数的入口点地址会发生什么?
例如,构造函数的地址已更改:
Export Ordinal Function Hint Entry Point
[+ ] 3 (0x0003) 2 (0x0002) ??0CLangManager@@QAE@XZ 0x00009CB0 (OLD DLL)
[+ ] 3 (0x0003) 2 (0x0002) ??0CLangManager@@QAE@XZ 0x00009760 (NEW DLL)
我是否应该重新编译使用该库的模块?
我测试了重新编译的库 - 使用新的入口点 - 使用已发布的可执行文件,一切正常。我不确定这种情况是否会隐藏一些副作用。
何时需要重新编译链接到DLL的可执行文件?
二进制兼容性何时会被破坏?
答案 0 :(得分:2)
这是使用DLL的好处之一 - 您可以更改它,只要您继续保持相同的功能签名,一切都会正常工作。链接在程序加载时发生,因此地址的更改不会产生任何差异。
您希望绝对肯定DLL中定义的任何类都没有任何内联方法,因为这些方法可能不适用于对象的任何内部更改。
当函数签名更改或公共成员变量更改对象中的位置时,二进制兼容性会中断。我会完全避免DLL中的公共成员变量。
编辑:如评论中所述,如果在类中添加或删除变量,更改其大小,也会遇到麻烦。如果在DLL之外创建对象(作为局部变量或通过new
),这将成为一个问题。您可以通过从DLL内部创建所有对象实例并将指针传递给调用者来避免这种情况。您还可以在课程中使用PIMPL idiom来避免问题。