深度理解:Windows DLL 二进制兼容性探究
使用C++开发工程代码的时候,一般采取模块化设计来降低项目的复杂度。一个典型的C++工程,一般分为一个EXE工程作为主启动进程,若干个DLL工程提供各种不同的功能集合。今天我们通过一个具体的实例来看看DLL的二进制兼容性。
研究环境
编译环境:VS2010
主EXE工程:Win32控制台应用,名称Test
DLL工程:MFC共享DLL,名称Function
工程代码
主EXE工程
主EXE工程采用VS2010内置的Win32控制台应用模板,在主工程中的main函数中调用了DLL工程的导出方法MyAdd。
#include "stdafx.h" #include "..\Function\Include.h" int _tmain(int argc, _TCHAR* argv[]) { printf("%d + %d = %d", 10, 20, MyAdd(10, 20)); getchar(); return 0; }
DLL工程
DLL工程采用VS2010内置的MFC共享DLL模板,在DLL工程中,我们定义并实现了一个导出方法MyAdd。这个方法的实现比较简单:接收两个整数,并返回这两个整数之和。
#include "stdafx.h" #include "Include.h" int MyAdd(int a, int b) { return a + b; }
第一种情况:主EXE工程调用DLL工程
分别编译EXE和DLL工程,执行EXE工程,可以得到以下结果:
在上述代码中,我们传入DLL方法了两个整数,10和20,DLL方法准确的返回了它们之和30。一切都是我们预期的。
第二种情况:DLL工程中的方法实现修改且主EXE工程不重新编译
我们将DLL工程实现代码进行修改,从计算两个整数之和修改为计算两个整数之乘积。
#include "stdafx.h" #include "Include.h" int MyAdd(int a, int b) { return a * b; }
在只编译DLL工程的情况下,我们直接执行主EXE工程,看看执行结果:
从执行结果来看,主EXE工程代码没有经过重新编译,但它”感知”到了DLL实现代码的变更,此场景我们认为:DLL的内部实现修改保持了其二进制的兼容性。
第三种情况:DLL工程中的方法声明修改且主EXE工程不重新编译
我们将DLL工程方法声明代码进行修改,从接收两个参数,我们修改为接收三个参数。
FUNCTION_API int MyAdd(int a, int b, int c); int MyAdd(int a, int b, int c) { return a + b; }
在只编译DLL工程的情况下,再次执行主EXE工程,看看执行结果:
我们看到,虽然DLL的参数增加了,但内部实现没有变更。但是主EXE工程在执行阶段提示找不到函数入口点,说明此时DLL工程的方法声明修改需要主EXE工程重新编译。此场景我们认为:DLL方法声明修改破坏了其二进制兼容性,任何DLL代码的方法声明的变更,其调用者必须重新编译。
结论
对于导出类C方法的DLL工程,当DLL内部实现代码变更时,DLL的调用者不需要重新编译。
对于导出类C方法的DLL工程,当DLL方法声明代码变更时,DLL的调用者需要重新编译。
相关推荐
- 深度理解:Linux设备驱动移植简介
- Posted on 04月06日
- 为什么向导式对话框中的取消按钮始终可用
- Posted on 07月04日
- 即使在计算机的世界,同时性也只是相对的
- Posted on 09月27日
- VS2019 v16.9 预览版3:MSVC后端更新汇总
- Posted on 01月23日
评论已关闭。