I am trying to compile an application involving both C and C++ files. With one particular header I face issues. The file in question (a C++ header file), would look something like this:
#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
I have a function fooObject()
which has a MyCCPObject
class type as a parameter. Also, one of the functions, foo3()
would be called from a C file. When the C compiler, compiles this header, I get the following error: "error: #20:identifier "class" is undefined"
. To avoid this, I had to:
fooObject()
declaration within compiler guards:#ifdef __cplusplus
int fooObject(MyCCPObject myCppObject);
#endif
MyCCPObject.h
:#ifdef __cplusplus
class MyCCPObject
{
public:
MyCCPObject(uint32_t val);
private:
uint32_t value;
};
#endif
Note: The MyCCPObject
would not be called in any C file. So, what would be a better approach, when I have a C++ header file, which involves:
extern
call to a C fileUse separate headers for your C and C++ code.
Move the foo3
declaration (including the __cplusplus
guards) inside a separate header. Let's call it Foo3.h
You now have the following files:
Task.h
- contains the declarations for foo1
and foo2
, fooObject
and includes MyCCPObject.h
Foo3.h
- contains the declarations for foo3
Task.cpp
- includes Task.h
and Foo3.h
and provides definitions for foo1
, foo2
and foo3
App.c
- includes Foo3.h
and uses foo3
From your build system (make, cmake etc.), when building the C++ library, add the files Task.h
, Foo3.h
, Task.cpp
(and the other files related to MyCCPObject
)
When building the C application, add only Foo3.h
and App.c
. That way, the other headers (which contain C++ code) will not be compiled and hence not give out any errors.
The makers of C++ wrote a 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 .
Option 1 : If you just want the C compiler to be able to parse your task.h header file, then you could hide the C++ parts my using #ifdef __cplusplus
:
#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
Option 2 : If you want to make the fooObject
function accessible from C, then you can change MyCppObject.h to provide the full class information to C++ and only a minimal typedef
for C. The typedef
makes sure that C understands just the class name MyCCPObject
without writing class
or struct
before it.
#ifdef __cplusplus
class MyCCPObject
{
public:
MyCCPObject(uint32_t val);
private:
uint32_t value;
};
#else
typedef struct MyCCPObject MyCCPObject;
#endif
and task.h to
#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
Please note that I needed to change the signature of fooObject
to take a pointer to the object as the C code does not see the complete class and does not know the size of the object.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.