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.
Expand|Select|Wrap|Line Numbers
- // 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.
Expand|Select|Wrap|Line Numbers
- /* 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.
Expand|Select|Wrap|Line Numbers
- // 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:
Expand|Select|Wrap|Line Numbers
- /* 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);
- }
Expand|Select|Wrap|Line Numbers
- # 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