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.