Re: call a C++ function from C?
On Mar 29, 3:03 pm, Pallav singh <singh.pal...@gmail.com> wrote:
can we call member functions (incl. virtual functions) of Class in C++
from C ?
For non-static member functions, you need an object for that kept by
the C++ wrapper.
Note, the following code is just a sketch. Essentially, a repository
of created objects is kept and is
referenced by handles of type integer.
I am sure it can be done much nicer and needs extra work for thread
safety and fault tolerance. The performance
can be improved by using a std::vector<> instead of a map but you may
need to keep track of used and free entries
in the repository.
The scheme works with polymorphism, though - if the factory function
"CreateMyClassObject()", or extra functions
added for this purpose, create objects of derived classes, virtual
member functions are called properly.
Make sure the MyBaseClass destructor is virtual to avoid pitfalls
here.
---------------------------------------------------------------------------=
----------------------
ExampleUsage.c:
#include "Wrapper.h"
....
int handle = CreateMyClassObject();
printf( "%d\n", ExampleMemberFunc( handle, 42 ) );
DestroyMyClassObject( handle );
---------------------------------------------------------------------------=
----------------------
MyClass.hpp:
class MyClass {
public:
int ExampleMemberFunc( int x );
};
---------------------------------------------------------------------------=
----------------------
Wrapper.h:
extern "C" {
int CreateMyClassObject(); // you need to add parameters as your
constructor requires.
void DestroyMyClassObject( int handle );
int ExampleMemberFunc( int handle, int x ); // note the added handle
param.
}
---------------------------------------------------------------------------=
----------------------
Wrapper.cc:
#include "MyClass.hpp" // defines the class you want to wrap.
#include <map>
static std::map<int, MyClass*> myclassrepository;
extern "C" {
int CreateMyClassObject() { // you need to add parameters as your
constructor requires.
myclassrepository[ myclassrepository.size() ] = new MyClass();
return myclassrepository.size() - 1; // index of created object.
}
void DestroyMyClassObject( int handle ) {
std::map<int, MyClass*>::iterator p = myclassrepository.find
( handle );
if ( p != myclassrepository.end() ) {
delete p->second;
myclassrepository.remove( p );
}
}
int ExampleMemberFunc( int handle, int x ) {
std::map<int, MyClass*>::iterator p = myclassrepository.find
( handle );
if ( p == myclassrepository.end() ) {
// Error Handling, no object for this handle.
return 0;
}
return p->second->ExampleMemberFunc( x );
}
} // extern "C"