我正在尝试将一个现有的第 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/