tags:

views:

209

answers:

2

Hi,

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.

Thanks Priyanshu

+23  A: 

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
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
@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
Thanks xtofl,Just one more thing, you have given example above....class C {public: bool foo( int arg );};If we have something likeclass C {public: bool foo( int arg, X *x);private : X *x;}};Then How can we write wrapper for that...is it possible :-(
Priyanshu
@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
@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
Priyanshu
@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
A: 

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