如何使用对C函数和类对象的外部调用来处理C++头文件

How to handle a C++ header file with a extern call to C function and a class object

本文关键字:外部调用 处理 C++ 文件 对象 何使用 函数      更新时间:2023-10-16

我正在尝试编译一个同时包含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"。为了避免这种情况,我不得不:

  1. fooObject()声明放在编译器保护中:
#ifdef __cplusplus
int fooObject(MyCCPObject myCppObject);
#endif
  1. 在头文件MyCCPObject.h的类声明中也放置编译器保护:
#ifdef __cplusplus
class MyCCPObject
{
public:
MyCCPObject(uint32_t val);
private:
uint32_t value;
};
#endif

注意:在任何C文件中都不会调用MyCCPObject。那么,当我有一个C++头文件时,有什么更好的方法呢?它涉及:

  1. 函数将涉及一个类对象
  2. 对C文件的extern调用

为C和C++代码使用单独的头。

foo3声明(包括__cplusplus保护(移动到一个单独的标头中。我们称之为Foo3.h您现在有以下文件:

  • Task.h-包含foo1foo2fooObject的声明,并包含MyCCPObject.h
  • Foo3.h-包含foo3的声明
  • Task.cpp-包括Task.hFoo3.h,并提供了foo1foo2foo3的定义
  • App.c-包括Foo3.h并使用foo3

在构建C++库时,从构建系统(make、cmake等(添加文件Task.hFoo3.hTask.cpp(以及与MyCCPObject相关的其他文件(

构建C应用程序时,只添加Foo3.hApp.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提供最小的typedeftypedef确保C只理解类名MyCCPObject,而无需在它之前写classstruct

#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代码看不到完整的类,也不知道对象的大小。