19

How can we call "C++" class member functions in 'C" code ?

I have two files .cpp, in which I have defined some classes with member functions and corresponding ".h" files which has included some other helping cpp/h files.

Now I want to call these functionality of CPP files in "C" file. How can I do it?

BЈовић
  • 62,405
  • 41
  • 173
  • 273
Priyanshu
  • 211
  • 1
  • 2
  • 3

1 Answers1

36

C has no thiscall notion. The C calling convention doesn't allow directly calling C++ object member functions.

Therefor, you need to supply a wrapper API around your C++ object, one that takes the this pointer explicitly, instead of implicitly.

Example:

// C.hpp
// uses C++ calling convention
class C {
public:
   bool foo( int arg );
};

C wrapper API:

// api.h
// uses C calling convention
#ifdef __cplusplus
extern "C" {
#endif

void* C_Create();
void C_Destroy( void* thisC );
bool C_foo( void* thisC, int arg );

#ifdef __cplusplus
}
#endif

Your API would be implemented in C++:

#include "api.h"
#include "C.hpp"

void* C_Create() { return new C(); }
void C_Destroy( void* thisC ) {
   delete static_cast<C*>(thisC);
}
bool C_foo( void* thisC, int arg ) {
   return static_cast<C*>(thisC)->foo( arg );
}

There is a lot of great documentation out there, too. The first one I bumped into can be found here.

xtofl
  • 40,723
  • 12
  • 105
  • 192
  • Thanks xtofl, Even I was thinking that we need to write wrapper functions, but I have some doubts: 1. How do we deal, if the class is inherited from some other classes, do we need wrappers for parent class functions also. 2. OR we need to write wrappers to functions which we are calling in "C" file only.... – Priyanshu Aug 27 '10 at 10:57
  • @Priyanshu: an interesting twist. C doesn't know virtual functions, but your API code does. So if `D` would override the (virtual) `foo` function, all you would need extra is a `D_Create` in your API. Much like the Factory pattern, I would say. But maybe you need to supply more concrete information. – xtofl Aug 27 '10 at 11:05
  • Thanks xtofl, Just one more thing, you have given example above.... class C { public: bool foo( int arg ); }; If we have something like class C { public: bool foo( int arg, X *x); private : X *x; } }; Then How can we write wrapper for that...is it possible :-( – Priyanshu Aug 27 '10 at 11:12
  • 2
    @Priyanshu: any pointer-to-object from C++ needs to be translated as a `void*` in the API functions. So for any class you need in the API, you would need a set of C wrapper functions. Of course, you try to keep the API as small as possible, which may induce some rethinking... – xtofl Aug 27 '10 at 11:40
  • 2
    @xtofl: not necessary a `void*`, you could forward-declare a `struct` for the purpose, using a different `struct` for each class in C++. Or more likely for each base class in C++, since C can't handle the polymorphism. – Steve Jessop Aug 27 '10 at 13:34
  • Hi Steve & xtoflt, Thanks for your help. But how can use struct as the class I am using is inherited from other classes also, and struct doesn't use inheritance....... – Priyanshu Aug 30 '10 at 03:21
  • @Priyanshu: you _can_ achieve that, but then you're really implementing OO support in C. I think what you need is 1. a `Create` function, and 2. functions that give access to the _interfaces_ your classes implement. But I think you're really asking a different question in the comments, here. – xtofl Aug 30 '10 at 06:55
  • @Priyanshu no major semantics difference between struct and class in C++. Just the default access mode is different: if you omit the access specifiers, struct assumes public while class assumes private. You can use 'struct C*' instead of 'void*': this is more descriptive and a common PIMPL use case in C. – Red.Wave Apr 16 '19 at 04:59