如何从C使用内部c ++类类型?

时间:2019-03-27 07:53:05

标签: c++ c types calling-convention cross-language

我有一个C ++类MyClass,该类声明了一个公共枚举类型MyEnum,我想在C文件中使用该枚举。我该怎么办?

我试图在C ++文件中声明函数,然后将所有内容都放置为extern "C",但可悲的是,我使用的是big_hugly_include.h中定义的某些函数,并且此标头不喜欢包含在{{1 }}(它给我一个external "C"错误)。

我不能(不想)更改此包含,我需要它,因为它定义了template with C linkage。我被卡住了吗?


my_function_from_big_include

my_class_definition.h

尝试1:class MyClass { public: // I would like to keep it that way as it is mainly used in C++ files typedef enum { MY_ENUM_0, MY_ENUM_1, MY_ENUM_2 } MyEnum; };

my_c_function_definition.c

尝试2:#include "my_class_definition.h" // I cannot remove this header #include "big_hugly_include.h" // foo is called in other C files void foo() { // I need to call this function with the enum from the C++ class // This doesn't work (class name scope does not exist in C) my_function_from_big_include(MyClass::MyEnum::MY_ENUM_0); }

my_c_function_definition.cpp

针对@artcorpse

进行了编辑

尝试3:#include "my_class_definition.h" extern "C" { // Error template with C linkage #include "big_hugly_include.h" // foo is called in other C files void foo() { // That would be ideal my_function_from_big_include(MyClass::MyEnum::MY_ENUM_0); } // end of extern "C" }

my_c_function_definition.cpp

2 个答案:

答案 0 :(得分:3)

  

我想在C文件中使用该枚举。我该怎么办?

C ++中的枚举概念起源于C,因此您只需要做的就是将该枚举与C未知的纯cpp API隔离开(记住名称改写,请参阅下文)。

由于C在类/结构枚举中不知道,因此无法使用它们。您必须定义全局范围枚举或创建将映射C ++特定枚举的枚举。

因此,在共享API应位于的位置创建单独的头文件。做这样的事情:

// shared C, C++ header
#ifdef __cplusplus
extern "C" 
{
#endif

enum YourMagicEnum {
    YourMagicEnumAValue,
    YourMagicEnumBValue,
    YourMagicEnumCValue,
};

void someFunction(YourMagicEnum x);

#ifdef __cplusplus
} // extern "C"
#endif

现在,extern "C"仅对于禁用名称修饰的函数是必需的(在C ++中,您可以执行函数重载,因此编译器会生成包含参数类型信息的名称)。

定义此类功能时,还应在该定义前面加上extern "C"

请记住,在该标头中只能放置C特定的特性和功能。

还请记住,VLA(可变长度数组)是C标准的,但不是C ++标准的(大多数编译器都支持C ++的VLA)。

有关更多信息,see this page

答案 1 :(得分:1)

您的Try2非常接近解决方案。尝试将包含外部extern“ C”移动。 我通常只是单独标记每个功能:

extern "C" void foo() 
{
...
}

这样做的好处是仅将一个符号导出为C符号,而不是尝试转换所有内容。