【背景】
平台A和平台B进行网络通信,通信接口以C语言结构体形式定义,存于名如interface_plata_platb.h的头文件内。正常情况下,平台A和平台B分别存储一份接口文件,其内容应该完全相同。由于同名的接口文件分两处存储,变更时很容易出现不同步的问题(例如两个平台分别A使用变更前后的接口文件),从而导致报文解析异常。
【问题】
请设计一种接口控制机制,以保证接口变更时两个平台采用一致的接口文件。为简化问题,假定:
1) 两个平台处理器的字节对齐方式和字节序均相同;
2) 可增加或删除接口结构体,结构体内可增删成员,但不可修改成员大小。
【实现】
此处给出一例简单实现。中心思想是在接口文件末尾定义一个变量记录"版本号",取值为其所在行数。这样,接口文件内的增删操作会反映到版本号的自动变化。
示例如下:
1 ///*: interface_plata_platb.h 2 #ifndef _INTERFACE_PLATA_PLATB_ 3 #define _INTERFACE_PLATA_PLATB_ 4 5 //定义接口宏(可增删和修改) 6 #define SOME_MACROS 0 7 8 //定义接口结构体(可增删成员和修改成员名,不可改变成员大小) 9 typedef struct { 10 unsigned int iCannotBeResized; 11 char cAddNewMemberBeforeOrAfter; 12 int iANewlyAppendedMember; 13 }T_IF_A; 14 15 //定义接口版本号(!!!禁止改动!!!) 16 const static unsigned char ucInterfaceVersion = __LINE__; 17 18 #endif
平台启动后,先通过网络通信获取对端的接口版本号,与本端的接口版本号对比。若两者相同则继续运行正常业务,否则发出警示。为简单展示接口版本号的使用,以下给出一个非跨平台的示例:
1 ///*: plata_interface.c 2 #include <stdio.h> 3 //#include "interface_plata_platb.h" 4 int main(void) { 5 printf("ucInterfaceVersion = %d ", ucInterfaceVersion); 6 return 0; 7 }
运行效果如下:
ucInterfaceVersion = 16
注意,考虑到增删操作会造成行数抵消,为保证接口版本号机制的正确性,应禁止同时做增删操作。考虑到接口变更的频率和规模较小,这一约束可通过口头或书面规则来保证。
【总结】
接口版本号机制是一种边界守护(Guard)的思想,同时也是一种用物理方法解决软件问题的思想。后者在编程语言的设计中时有体现,例如Java包名采用域后缀倒置后加上自定义的包名的格式,以保障包命名的唯一性。