如何通过对 C 函数的外部调用和 class object 处理 C++ header 文件
How to handle a C++ header file with a extern call to C function and a class object
我正在尝试编译一个同时涉及 C 和 C++ 文件的应用程序。对于一个特定的 header 我遇到了问题。有问题的文件(C++ header 文件)看起来像这样:
#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
class 类型作为参数。此外,其中一个函数 foo3()
将从 C 文件中调用。
当 C 编译器编译此 header 时,出现以下错误:"error: #20:identifier "class" is undefined"
。为了避免这种情况,我不得不:
- 将
fooObject()
声明放在编译器保护中:
#ifdef __cplusplus
int fooObject(MyCCPObject myCppObject);
#endif
- 将编译器保护也放在 header 文件的 class 声明中
MyCCPObject.h
:
#ifdef __cplusplus
class MyCCPObject
{
public:
MyCCPObject(uint32_t val);
private:
uint32_t value;
};
#endif
注意:MyCCPObject
不会在任何 C 文件中调用。
那么,当我有一个 C++ header 文件时,什么是更好的方法,其中涉及:
- 函数将涉及 class object
- A
extern
调用 C 文件
C++ 的创造者写了一个FAQ which is also giving some guidance on how to mix C and C++. They are also looking at the possibility to use C++ objects from C code。
选项 1:如果您只是希望 C 编译器能够解析您的 task.h 头文件,那么您可以使用 [= 隐藏 C++ 部分13=]:
#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:如果要使 fooObject
函数可从 C 访问,则可以更改 MyCppObject.h 以提供完整的 class 信息到 C++,只有最小的 typedef
用于 C。 typedef
确保 C 只理解 class 名称 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 代码看不到完整的 class 并且不知道对象的大小.
为您的 C 和 C++ 代码使用单独的 header。
将 foo3
声明(包括 __cplusplus
守卫)移到单独的 header 中。我们称它为 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
从您的构建系统(make、cmake 等)构建 C++ 库时,添加文件 Task.h
、Foo3.h
、Task.cpp
(以及与MyCCPObject
)
构建 C 应用程序时,仅添加 Foo3.h
和 App.c
。这样,其他 headers(包含 C++ 代码)将不会被编译,因此不会给出任何错误。
我正在尝试编译一个同时涉及 C 和 C++ 文件的应用程序。对于一个特定的 header 我遇到了问题。有问题的文件(C++ header 文件)看起来像这样:
#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
class 类型作为参数。此外,其中一个函数 foo3()
将从 C 文件中调用。
当 C 编译器编译此 header 时,出现以下错误:"error: #20:identifier "class" is undefined"
。为了避免这种情况,我不得不:
- 将
fooObject()
声明放在编译器保护中:
#ifdef __cplusplus
int fooObject(MyCCPObject myCppObject);
#endif
- 将编译器保护也放在 header 文件的 class 声明中
MyCCPObject.h
:
#ifdef __cplusplus
class MyCCPObject
{
public:
MyCCPObject(uint32_t val);
private:
uint32_t value;
};
#endif
注意:MyCCPObject
不会在任何 C 文件中调用。
那么,当我有一个 C++ header 文件时,什么是更好的方法,其中涉及:
- 函数将涉及 class object
- A
extern
调用 C 文件
C++ 的创造者写了一个FAQ which is also giving some guidance on how to mix C and C++. They are also looking at the possibility to use C++ objects from C code。
选项 1:如果您只是希望 C 编译器能够解析您的 task.h 头文件,那么您可以使用 [= 隐藏 C++ 部分13=]:
#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:如果要使 fooObject
函数可从 C 访问,则可以更改 MyCppObject.h 以提供完整的 class 信息到 C++,只有最小的 typedef
用于 C。 typedef
确保 C 只理解 class 名称 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 代码看不到完整的 class 并且不知道对象的大小.
为您的 C 和 C++ 代码使用单独的 header。
将 foo3
声明(包括 __cplusplus
守卫)移到单独的 header 中。我们称它为 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
从您的构建系统(make、cmake 等)构建 C++ 库时,添加文件 Task.h
、Foo3.h
、Task.cpp
(以及与MyCCPObject
)
构建 C 应用程序时,仅添加 Foo3.h
和 App.c
。这样,其他 headers(包含 C++ 代码)将不会被编译,因此不会给出任何错误。