If you want to call class methods from C++ from within C, use a class wrapper.
One advantage of this method is that the C++ class remains unmodified, and can
even exist in a library.
First, let's define the C++ class, "Circle". For simplicity, we'll do everything
in a .h file, but it works just as well for classes declared in a .h and defined
in a .cpp file.
Now let's declare a C++ wrapper for this class, which declares extern C methods,
which can be used from within C. This code must compile in both C++ and C files.
Use void * to point to class instances. Note the use of #ifdef __cplusplus.
Now define the extern functions. These will only be compiled as C++, so classes
can be referenced.
We can now use these extern C functions to access the C++ classes from C. Here
is a C main function example:
Here is a sample make file which creates a "mixed" executable.
Submitted by Jim Rogers
One advantage of this method is that the C++ class remains unmodified, and can
even exist in a library.
First, let's define the C++ class, "Circle". For simplicity, we'll do everything
in a .h file, but it works just as well for classes declared in a .h and defined
in a .cpp file.
Code:
// Circle.h - a C++ class
#ifndef CIRCLE_H
#define CIRCLE_H
class Circle {
public:
Circle(float radius):_radius(radius) {}
float getArea() { return 3.14159 * _radius * _radius; }
private:
float _radius;
};
#endif
which can be used from within C. This code must compile in both C++ and C files.
Use void * to point to class instances. Note the use of #ifdef __cplusplus.
Code:
/* Circle_C.h - must compile in both C and C++ */
#ifndef Circle_C_H
#define Circle_C_H
#ifdef __cplusplus
extern "C" {
#endif
extern void *Circle_C_new(float radius);
extern void Circle_C_delete(void *circle);
extern float Circle_C_getArea(void *circle);
#ifdef __cplusplus
}
#endif
#endif
can be referenced.
Code:
// Circle_C.cpp - extern C function definitions
#include "Circle_C.h"
#include "Circle.h"
extern void *Circle_C_new(float radius) {
return new Circle(radius);
}
extern void Circle_C_delete(void *circle) {
Circle *c = (Circle *)circle;
delete c;
}
extern float Circle_C_getArea(void *circle) {
Circle *c = (Circle *)circle;
return c->getArea();
}
is a C main function example:
Code:
/* mixed.c - a C file that accesses C++ methods */
#include <stdio.h>
#include "Circle_C.h"
void main() {
float radius = 1.5;
// Get a pointer to a Circle object
void *circle = Circle_C_new(radius);
// Pass the Circle object to the wrapper methods
float area = Circle_C_getArea(circle);
printf ("Circle of radius %f has area %f\n", radius, area);
// Free the Circle object memory
Circle_C_delete(circle);
}
Code:
# Makefile - creates the executable "mixed". Must link the stdc++ library mixed: main.o Circle.o gcc -lstdc++ -o mixed main.o Circle_C.o # Compile main as C main.o: main.c gcc -c main.c -o main.o # Compile Circle_C as C++ Circle_C.o: Circle_C.cpp g++ -c Circle_C.cpp -o Circle_C.o
Comment