管理来自多个供应商的冗余 typedef

发布于 2024-08-14 05:33:09 字数 532 浏览 1 评论 0原文

在 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 中的定义根本不允许这样做。

What are some of the best ways to manage redundant typedefs used for platform independence from multiple middleware (operating systems, protocol stacks) vendors in the C programming language.

e.g.:
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 ... */

At some point the compiler recognizes that it has two redundant typedef symbols and bails out with an error because this is simply not allowed by definition in C.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

云胡 2024-08-21 05:33:09

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

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

One possible way to do this without modifying the vendor's header would be to use the preprocessor with some header wrappers, e.g.

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;

This would result in the vendor's code generating different typedefs but hopefully mapped to the same actual type (unsigned char in the example). If the vendors are using different underlying types for the same type names then the method will likely not work.

姜生凉生 2024-08-21 05:33:09

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

祝你好运。

That's a toughie. If I had to do something, I'd probably hold my nose and modify the third-party header-files -- possibly using macros to obtain conditional compilation of the offending typedefs.

Good luck.

筑梦 2024-08-21 05:33:09

如果供应商对反馈做出响应,您可以请求他们将这些通用类型定义移至单独的文件中,例如 types.h。如果将它们隔离在单独的文件中,则管理起来会容易得多。解决方案可以很简单,只需删除它们的 types.h 并添加您自己的特定于项目的 types.h 即可执行项目中需要执行的任何操作。

更好的是,请求他们在 stdint.h 中使用标准 C typedef,即 uint16_t

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

If the vendor is responsive to feedback, you could beg them to move those generic type definitions into a separate file, e.g. types.h. If they're isolated in a separate file, it's much easier to manage. The solution could be as simple as removing their types.h and adding your own project-specific types.h which can do whatever it needs to do in your project.

Even better, beg them to use the standard C typedefs in stdint.h, i.e. uint16_t.

Otherwise, I'd suggest a modification to the vendor header files, done as cleanly as possible so it's easy to re-do when they next release code. Of course this all goes in your VCS so you can track exactly what changes you made!

罪歌 2024-08-21 05:33:09

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

正如史蒂夫所建议的,修改头文件可能是最好的解决方案,具体取决于供应商发布其产品新版本的频率。开销可能会变得相当高。

One approach, although it could be a lot of work, is to build your own "wrapper" layers which provide only the functionality you need from each of the middleware vendors. If you keep each wrapper in its own compilation unit (.c file) that's the only place you'll need to refer to the vendor's header file. That gives you a way to prevent the conflicting types from "leaking" into your application, as you can use your own typedefs and translate them to the vendor-specific types in the wrapper.

As Steve suggested, modifying the header files might be the best solution, depending on how often the vendor ships new versions of their stuff. The overhead could get pretty high.

故事还在继续 2024-08-21 05:33:09

如果您可以选择对自己的代码使用 C++ 编译(即使它本质上是 C 代码),您可以这样创建命名空间包装器:

然后

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

vendorA_target.hvendorB_OS_types.h

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

在您自己的代码中。包含这些标头来代替原始标头,并使用作用域解析,或者如果您确定具有相同名称的类型具有相同或兼容的定义,只需使用 using 指令:

using vendorB::WORD
WORD timeout = 100 ;

vendorA::WORD x = 0xffff ;

请注意,extern "C" 宏条件中内部包含了 code> 包装器,则不需要包装器 - 但这不会造成伤害。

使用 C++ 编译 C 代码不会产生任何开销,但它确实有更严格的类型一致性检查,这虽然有利于代码质量,但可能会导致其他问题;特别是如果第三方标头包含对 C++ 无效的代码。如果标头在 __cplusplus 宏条件中已经有 extern "C" 声明,那么它们已经是“C++ 就绪”的,您可能不会遇到任何此类问题。

不幸的是,这种方法不能解决同名预处理器宏的问题。如果您遇到此问题,您可能必须先 #undef 一个标头中的宏,然后再包含另一个标头,或者修改标头。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文