我正在尝试编译一个同时包含C和C++文件的应用程序。有一个特殊的标题,我面临问题。有问题的文件(C++头文件(看起来像这样:
#ifndef TASK_H
#define TASK_H
#include "MyCCPObject.h"
int foo1(int);
int foo2(int);
int fooObject(MyCCPObject myCppObject); // Function involves a Class "MyCCPObject" type
#ifdef __cplusplus
extern "C" {
#endif
int foo3(void); // Function called in a C file
#ifdef __cplusplus
}
#endif
#endif //TASK_H
我有一个函数fooObject()
,它有一个MyCCPObject
类类型作为参数。此外,其中一个函数foo3()
将从C文件中调用。当C编译器编译这个头时,我得到以下错误:"error: #20:identifier "class" is undefined"
。为了避免这种情况,我不得不:
- 将
fooObject()
声明放在编译器保护中:
#ifdef __cplusplus
int fooObject(MyCCPObject myCppObject);
#endif
- 在头文件
MyCCPObject.h
的类声明中也放置编译器保护:
#ifdef __cplusplus
class MyCCPObject
{
public:
MyCCPObject(uint32_t val);
private:
uint32_t value;
};
#endif
注意:在任何C文件中都不会调用MyCCPObject
。那么,当我有一个C++头文件时,有什么更好的方法呢?它涉及:
- 函数将涉及一个类对象
- 对C文件的
extern
调用
为C和C++代码使用单独的头。
将foo3
声明(包括__cplusplus
保护(移动到一个单独的标头中。我们称之为Foo3.h
您现在有以下文件:
Task.h
-包含foo1
和foo2
、fooObject
的声明,并包含MyCCPObject.h
Foo3.h
-包含foo3
的声明Task.cpp
-包括Task.h
和Foo3.h
,并提供了foo1
、foo2
和foo3
的定义App.c
-包括Foo3.h
并使用foo3
在构建C++库时,从构建系统(make、cmake等(添加文件Task.h
、Foo3.h
、Task.cpp
(以及与MyCCPObject
相关的其他文件(
构建C应用程序时,只添加Foo3.h
和App.c
。这样,其他头(包含C++代码(将不会被编译,因此不会发出任何错误。
C++的制作者编写了一个常见问题解答,其中还提供了一些关于如何混合C和C++的指导。他们也在研究从C代码中使用C++对象的可能性。
选项1:如果你只想让C编译器能够解析你的task.h头文件,那么你可以使用#ifdef __cplusplus
:隐藏C++部分
#ifndef TASK_H
#define TASK_H
#ifdef __cplusplus
#include "MyCCPObject.h"
int foo1(int);
int foo2(int);
int fooObject(MyCCPObject myCppObject); // Function involves a Class "MyCCPObject" type
extern "C" {
#endif
int foo3(void); // Function called in a C file
#ifdef __cplusplus
}
#endif
#endif //TASK_H
选项2:如果您想从C访问fooObject
函数,那么您可以更改MyCppObject.h以向C++提供完整的类信息,而仅为C提供最小的typedef
。typedef
确保C只理解类名MyCCPObject
,而无需在它之前写class
或struct
。
#ifdef __cplusplus
class MyCCPObject
{
public:
MyCCPObject(uint32_t val);
private:
uint32_t value;
};
#else
typedef struct MyCCPObject MyCCPObject;
#endif
和task.h到
#ifndef TASK_H
#define TASK_H
#include "MyCCPObject.h"
int foo1(int);
int foo2(int);
#ifdef __cplusplus
extern "C" {
#endif
int fooObject(MyCCPObject *myCppObject); // Function involves a Class "MyCCPObject" type
int foo3(void); // Function called in a C file
#ifdef __cplusplus
}
#endif
#endif //TASK_H
请注意,我需要更改fooObject
的签名以获取指向对象的指针,因为C代码看不到完整的类,也不知道对象的大小。