423,491 Members | 2,205 Online
Bytes IT Community
Submit an Article
Got Smarts?
Share your bits of IT knowledge by writing an article on Bytes.

Calling C++ class methods from C

P: 1
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.
Expand|Select|Wrap|Line Numbers
  1. // Circle.h - a C++ class
  2.  
  3. #ifndef CIRCLE_H
  4. #define CIRCLE_H
  5.  
  6. class Circle {
  7.     public:
  8.         Circle(float radius):_radius(radius) {}
  9.         float getArea() { return 3.14159 * _radius * _radius; }
  10.     private:
  11.         float _radius;
  12. };
  13.  
  14. #endif
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.
Expand|Select|Wrap|Line Numbers
  1. /* Circle_C.h - must compile in both C and C++ */
  2.  
  3. #ifndef Circle_C_H
  4. #define Circle_C_H
  5.  
  6.     #ifdef __cplusplus
  7.     extern "C" {
  8.     #endif
  9.  
  10.     extern void *Circle_C_new(float radius);
  11.     extern void  Circle_C_delete(void *circle);
  12.     extern float Circle_C_getArea(void *circle);
  13.  
  14.     #ifdef __cplusplus
  15.     }
  16.     #endif
  17.  
  18. #endif
Now define the extern functions. These will only be compiled as C++, so classes
can be referenced.
Expand|Select|Wrap|Line Numbers
  1. // Circle_C.cpp - extern C function definitions
  2.  
  3. #include "Circle_C.h"
  4. #include "Circle.h"
  5.  
  6. extern void *Circle_C_new(float radius) {
  7.     return new Circle(radius);
  8. }
  9.  
  10. extern void Circle_C_delete(void *circle) {
  11.     Circle *c = (Circle *)circle;
  12.     delete c;
  13. }
  14.  
  15. extern float Circle_C_getArea(void *circle) {
  16.     Circle *c = (Circle *)circle;
  17.     return c->getArea();
  18. }
We can now use these extern C functions to access the C++ classes from C. Here
is a C main function example:
Expand|Select|Wrap|Line Numbers
  1.  /* mixed.c - a C file that accesses C++ methods */
  2.  
  3. #include <stdio.h>
  4. #include "Circle_C.h"
  5.  
  6. void main() {
  7.     float radius = 1.5;
  8.  
  9.     // Get a pointer to a Circle object
  10.     void *circle = Circle_C_new(radius);
  11.  
  12.     // Pass the Circle object to the wrapper methods
  13.     float area = Circle_C_getArea(circle);
  14.  
  15.     printf ("Circle of radius %f has area %f\n", radius, area);
  16.  
  17.     // Free the Circle object memory
  18.     Circle_C_delete(circle);
  19. }
Here is a sample make file which creates a "mixed" executable.
Expand|Select|Wrap|Line Numbers
  1. # Makefile - creates the executable "mixed".  Must link the stdc++ library
  2.  
  3. mixed: main.o Circle.o
  4.     gcc -lstdc++ -o mixed main.o Circle_C.o
  5.  
  6. # Compile main as C
  7. main.o: main.c
  8.     gcc -c main.c -o main.o
  9.  
  10. # Compile Circle_C as C++
  11. Circle_C.o: Circle_C.cpp
  12.     g++ -c Circle_C.cpp -o Circle_C.o
Submitted by Jim Rogers
Nov 7 '11 #1
Share this Article
Share on Google+
2 Comments


P: 1
Thanks a lot. It really helped for my work . YOU ROCKS....
Jun 25 '15 #2

P: 1
GREAT! It really helped;
Jun 13 '18 #3