使用C编程语言管理多个中间件(操作系统,协议栈)供应商的平台独立冗余typedef的最佳方法有哪些。
例如为:
的 target.h
/* inclusion lock etc */
typedef char CHAR;
typedef unsigned char BYTE;
typedef unsigned short int WORD;
/* ... more of the same ... */
OS_types.h
/* inclusion lock etc */
typedef char CHAR;
typedef unsigned char BYTE;
typedef unsigned short int WORD;
/* ... more of the same ... */
在某些时候,编译器会识别出它有两个冗余的typedef符号并且出现错误,因为C中的定义根本不允许这样做。
答案 0 :(得分:6)
在不修改供应商标题的情况下执行此操作的一种可能方法是将预处理器与一些标头包装器一起使用,例如
<强> mytypes.h 强>
#define BYTE VENDOR1_BYTE
#include <vendor1/types.h>
#undef BYTE
#define BYTE VENDOR2_BYTE
#include <vendor2/types.h>
#undef BYTE
typedef unsigned char BYTE;
这会导致供应商的代码生成不同的typedef,但希望映射到相同的实际类型(示例中的unsigned char)。如果供应商对相同的类型名称使用不同的基础类型,那么该方法可能不起作用。
答案 1 :(得分:2)
这是一个艰难的过程。如果我必须做某事,我可能会嗤之以鼻并修改第三方头文件 - 可能使用宏来获取有问题的typedef的条件编译。
祝你好运。答案 2 :(得分:1)
如果供应商对反馈做出响应,您可以请求他们将这些通用类型定义移动到单独的文件中,例如: types.h
。如果它们被隔离在一个单独的文件中,那么它就更容易管理。解决方案可以简单到删除他们的types.h
并添加您自己的项目特定types.h
,它可以在您的项目中执行任何操作。
更好的是,请求他们在stdint.h
中使用标准的C typedef,即uint16_t
。
否则,我建议对供应商头文件进行修改,尽可能干净地完成,以便在下次发布代码时轻松重做。当然这一切都在您的VCS中,因此您可以准确地跟踪您所做的更改!
答案 3 :(得分:0)
虽然可能需要做很多工作,但有一种方法是构建自己的“包装”层,这些层只提供每个中间件供应商所需的功能。如果将每个包装器保留在自己的编译单元(.c文件)中,那么这是您需要引用供应商头文件的唯一位置。这为您提供了一种方法来防止冲突类型“泄漏”到您的应用程序中,因为您可以使用自己的typedef并将它们转换为包装器中特定于供应商的类型。
正如Steve建议的那样,修改头文件可能是最好的解决方案,具体取决于供应商发布其新版本内容的频率。开销可能会很高。
答案 4 :(得分:0)
如果您可以选择为自己的代码使用C ++编译(即使它本质上是C代码),您可以创建名称空间包装器:
namespace vendorA
{
extern "C"
{
#include <target.h>
}
}
namespace vendorB
{
extern "C"
{
#include <target.h>
}
}
然后在你自己的代码中。包括这些标题代替原文,并使用范围解析,或者如果您确定具有相同名称的类型具有相同或兼容的定义,只需使用using指令:
using vendorB::WORD
WORD timeout = 100 ;
vendorA::WORD x = 0xffff ;
请注意,如果标题已在extern "C"
宏条件中内部包含它们,则不需要__cplusplus
包装器 - 但它不会受到伤害。
使用C ++编译C代码不会产生任何开销,但它确实有更严格的类型comformaty检查,虽然这对您的代码质量有好处,但可能会引起其他问题;特别是如果第三方标头包含与C ++无效的代码。如果标头在extern "C"
宏条件中已经有__cplusplus
声明,那么它们已经打算成为“C ++就绪”,您可能没有任何此类问题。
不幸的是,此方法无法解决具有相同名称的预处理器宏问题。如果您遇到这个问题,可能需要在包含另一个标头之前从一个标头中#undef,或者修改标题。