Reputation: 3604
Is there a simple way to work with C++ objects directly from C? I want to expose some classes from C++ to C or to FFI(foreign function interface). Sure, I can write a stuff like that:
class Foo{
....
};
void *make_foo(...){
Foo *ptr = new Foo(..)
return static_cast<void *>(ptr);
}
..
int *foo_method1(void *fooptr, ...){
Foo *ptr = static_cast<Foo*>(fooptr);
}
But there is a simpler method?
Upvotes: 7
Views: 318
Reputation: 21721
If it's possible, then have your classes derive from a struct. You can then use pointers to this struct in the C code:
// C++ code
extern "C" struct Cfoo {};
extern "C" struct Cbar {};
class foo : public Cfoo {};
class bar : public Cbar {};
// C API
extern "C" {
struct Cfoo;
struct Cbar;
}
It's not strictly an error, however gcc at least warns about converting between pointers with different types.
void foo (void) {
struct Cfoo * pf;
struct Cbar * pb;
pf = pb; // gcc warns
}
If you cannot inherit, then use a similar idea but have the C structure store a pointer to the C++ object, and again just forward declare the structures in the C API:
// C++ code
class foo {};
class bar {};
extern "C" struct Cfoo { foo * pFoo; };
extern "C" struct Cbar { bar * pBar; };
// C API
extern "C" {
struct Cfoo;
struct Cbar;
}
The disadvantage here is that the lifetime of the Cfoo and Cbar object needs to be taken care of.
Upvotes: 1
Reputation: 4469
You can use Verrazano/Fetter to generate CFFI bindings for C++ code. But it requires GCC-XML and I'm not sure about its portability.
Upvotes: 1
Reputation: 13521
There's not really a simpler way to do it. You could use SWIG to go to another language with user defined types that are more than aggregates of data, but converting to C you'll have to use C's idea of objects.
Upvotes: 1
Reputation: 40224
You almost there. Prefix your standalone functions with extern "C"
to turn off the C++ compiler's name mangling.
For example:
extern "C" void *make_foo(...){
Foo *ptr = new Foo(..)
return static_cast<void *>(ptr);
}
Upvotes: 7
Reputation: 564413
That, in general, is the simplest method.
Remember, too, that you'll need to use extern "C"
on all of your C "wrapper" methods, as well.
Upvotes: 8