c++ - 将 C++ 命名空间枚举包装到 C 接口(interface)

标签 c++ c enums extern

我正在尝试将一个现有的第 3 方 C++ 库包装到一个 C 接口(interface),以便它可以用于另一种语言的绑定(bind)。我无法弄清楚如何包装命名空间枚举,而不是仅仅重新定义它:

// Existing C++ 3rd party library header
namespace foo {
    enum Fruit {
        APPLE = 0,
        ORANGE
    }
}

然后我用 extern "C" block 包装了我的 wrapped.{h,cpp} ,但我不知道如何导出 foo::Fruit 枚举到 C 接口(interface)中

// wrapped.h
#ifdef __cplusplus
extern "C" {
#endif

// I don't want to do this
typedef enum Fruit {
    APPLE = 0,
    ORANGE
} Fruit;

#ifdef __cplusplus
}
#endif
#endif

是否可以将 C++ 库中的(镜像)foo::Fruit 作为 Fruit 导出到我的 C 包装器中?

最佳答案

编辑:我刚刚注意到您想包装现有的库而不修改它。

我担心你要倒霉了。一般而言,没有 C 编译器阻塞的情况下,无法仅从 C++ 代码中提取枚举成员。

在实践中,您可以选择是否以编程方式将您自己的枚举集转换为界面中的 C++ 版本,尝试准确地镜像 C++ 并放置一堆静态断言以进行双重检查,或者甚至在理论上什至通过脚本过滤掉它们。

恐怕这里没有好的选择。作为记录,我倾向于选择这些糟糕选项中的第一个。


就我个人而言,我可能会偷懒而坚持使用 C 版本。

不过,如果需要并且常量的数量很大,您可以使用一些宏魔法来根据需要使用 C 风格的“命名空间”获得单个定义。

首先是通过宏定义所有枚举条目的单个 header :

/* Fruit.h */
FOO_ENUM(APPLE) = 0,
FOO_ENUM(ORANGE)

然后在 C 头文件中:

/* C interface */
typedef enum {
#   define FOO_ENUM(id) FOO_##id
#   include "Fruit.h"
#   undef FOO_ENUM
} Foo_Fruit_t;

最后在 C++ 头文件中:

// C++ interface
namespace Foo {
    enum Fruit_t {
#       define FOO_ENUM(id) id
#       include "Fruit.h"
#       undef FOO_ENUM
    };
}

当然有很多选择。例如,如果您不介意在 C++ 中污染全局命名空间,则始终可以直接在 C 接口(interface)中定义完整的枚举,并在 C++ 版本的定义中复制各个枚举成员。

关于c++ - 将 C++ 命名空间枚举包装到 C 接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20792121/

相关文章:

c# - 包含语句 : c++

c++ - 使用 FileStorage API 加载的 cv::Mat 的可用内存

c++ - 我的 iOS6 编译的静态库可以检查 iOS 应用程序的编译版本吗?

c - C 有任何内置函数吗?

无法打印 '1' ?

c - 为什么每次调整终端大小时函数 tgetnum ("co") 不会更新?

c++ - 是否有任何操纵器可以将枚举值打印为字符串?

java - Java 中的反序列化枚举

c++ - 现代 OpenGL 3.0 : How to move a 2D vbo on screen

c - C 枚举定义中的位移位有什么作用?