7

在 C 编程语言中,管理来自多个中间件(操作系统、协议栈)供应商的用于平台独立性的冗余 typedef 的最佳方法是什么?

例如:
目标.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 中的定义根本不允许这样做。

4

5 回答 5

6

在不修改供应商标头的情况下执行此操作的一种可能方法是将预处理器与一些标头包装器一起使用,例如

我的类型.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)。如果供应商对相同的类型名称使用不同的底层类型,则该方法可能不起作用。

于 2009-12-10T20:43:01.057 回答
2

那是个硬汉。如果我必须做某事,我可能会捏着鼻子修改第三方头文件——可能使用宏来获得有问题的 typedef 的条件编译。

祝你好运。

于 2009-12-10T19:41:45.457 回答
1

如果供应商响应反馈,您可以请求他们将这些泛型类型定义移动到单独的文件中,例如types.h. 如果它们被隔离在一个单独的文件中,则管理起来会容易得多。该解决方案可以像删除它们types.h并添加您自己的项目特定一样简单,types.h它可以在您的项目中做任何需要做的事情。

更好的是,请求他们使用标准的 C 类型定义 in stdint.h,即uint16_t.

否则,我建议对供应商头文件进行修改,尽可能干净地完成,以便在下次发布代码时轻松重做。当然,这一切都在您的 VCS 中,因此您可以准确跟踪您所做的更改!

于 2009-12-15T08:08:46.847 回答
0

If you have the option to use C++ compilation for your own code (even if it is essentially C code) you could create namespace wrappers thus:

vendorA_target.h

namespace vendorA
{
    extern "C"
    {
        #include <target.h>
    }
}

vendorB_OS_types.h

namespace vendorB
{
    extern "C"
    {
        #include <target.h>
    }
}

Then in your own code. include these headers in place of the originals, and use scope-resolution, or if you are certain that types with the same name have identical or compatible definitions, simply us a using directive:

using vendorB::WORD
WORD timeout = 100 ;

vendorA::WORD x = 0xffff ;

Note that the extern "C" wrappers are not necessary if the headers already have them internally in __cplusplus macro conditionals - but it won't hurt.

Using C++ to compile C code imposes no overhead, but it does have stricter type comformaty checking, which while good for your code quality, may cause other headaches; especially if the third-party headers contain code that is invalid as C++. If the headers already have extern "C" declarations in __cplusplus macro conditionals, then they are already intended to be "C++-ready" and you may not have any such problems.

Unfortunately this method will not solve the problem of preprocessor macros with the same name. If you have that problem, you may have to #undef the macros from one header before including the other, or modify the headers.

于 2009-12-10T21:36:37.333 回答
0

一种方法,尽管可能需要大量工作,但是构建您自己的“包装”层,它只提供您需要的每个中间件供应商的功能。如果您将每个包装器保存在其自己的编译单元(.c 文件)中,那么这是您需要参考供应商头文件的唯一位置。这为您提供了一种防止冲突类型“泄漏”到应用程序中的方法,因为您可以使用自己的 typedef 并将它们转换为包装器中的供应商特定类型。

正如史蒂夫建议的那样,修改头文件可能是最好的解决方案,这取决于供应商多久发布一次新版本的东西。开销可能会变得相当高。

于 2009-12-10T19:46:18.997 回答