如何使用C中的内部c ++类类型? [重复]

问题描述 投票:3回答:2

我有一个C ++类MyClass声明一个公共枚举类型MyEnum,我想在C文件中使用该枚举。我怎样才能做到这一点 ?

我试图在C ++文件中声明我的函数,然后将所有内容都设置为extern "C",但遗憾的是我使用的是big_hugly_include.h中定义的一些函数,这个标题不喜欢被包含为external "C"(它给了我一个template with C linkage错误)。

我不能(不想)改变这个包含,我需要它,因为它定义了my_function_from_big_include。我被困了?


my_class_definition.h

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;
};

尝试1:my_c_function_definition.c

#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);
}

尝试2:my_c_function_definition.cpp

#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"
}

编辑以回应@artcorpse

尝试3:my_c_function_definition.cpp

#include "my_class_definition.h"

// Error multiple definition of [...]
// Error undefined reference to [...]
#include "big_hugly_include.h"

extern "C"
{
// 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"
}
c++ c types calling-convention cross-language
2个回答
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 ++标准(大多数编译器支持VLA for C ++)。

有关see this page的更多信息。


1
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.