I am wrapping a simple C++ inheritance hierarchy into "object-oriented" C. I'm trying to figure out if there any gotchas in treating the pointers to C++ objects as pointers to opaque C structs. In particular, under what circumstances would the derived-to-base conversion cause problems?
The classes themselves are relatively complex, but the hierarchy is shallow and uses single-inheritance only:
// A base class with lots of important shared functionality
class Base {
    public:
    virtual void someOperation();
    // More operations...
    private:
    // Data...
};
// One of several derived classes
class FirstDerived: public Base {
    public:
    virtual void someOperation();
    // More operations...
    private:
    // More data...
};
// More derived classes of Base..
I am planning on exposing this to C clients via the following, fairly standard object-oriented C:
// An opaque pointers to the types
typedef struct base_t base_t;
typedef struct first_derived_t first_derived_t;
void base_some_operation(base_t* object) {
     Base* base = (Base*) object;
     base->someOperation();
}
first_derived_t* first_derived_create() {
     return (first_derived_t*) new FirstDerived();
}
void first_derived_destroy(first_derived_t* object) {
     FirstDerived* firstDerived = (FirstDerived*) object;
     delete firstDerived;
}
The C clients only pass around pointers to the underlying C++ objects and can only manipulate them via function calls. So the client can finally do something like:
first_derived_t* object = first_derived_create();
base_some_operation((base_t*) object); // Note the derived-to-base cast here
...
and have the virtual call to FirstDerived::someOperation() succeed as expected.
These classes are not standard-layout but do not use multiple or virtual inheritance. Is this guaranteed to work?
Note that I have control over all the code (C++ and the C wrapper), if that matters.