I recall I saw somewhere some code which used to have a struct as a base class, and a C++ class as a derived class
struct Base_Struct
{
}
class Derived : Base_Struct
{
...
}
And the point is that a pointer to Base_Struct* was passed from the C++ files to some C files which then managed to use some function pointers in Base_Struct.
My question is: if I pass Base_Struct* to a C file, will the C code be able to use the Base_Struct completely? What about the derived class?
Structs are value types while classes are reference types. Structs can be instantiated without using a new operator. A struct cannot inherit from another struct or class, and it cannot be the base of a class.
Yes, struct can inherit from class in C++. In C++, classes and struct are the same except for their default behaviour with regards to inheritance and access levels of members.
In C++, structs and classes are pretty much the same; the only difference is that where access modifiers (for member variables, methods, and base classes) in classes default to private, access modifiers in structs default to public.
Yes you can. In c++, class and struct are kind of similar. We can define not only structure inside a class, but also a class inside one. It is called inner class.
If I pass
Base_Struct*
to a C file, will the C code be able to use theBase_Struct
completely?
If it's a standard-layout class, and the C compiler uses the same ABI for such classes as the C++ compiler, then it can access all the data members. Obviously, it couldn't access any member functions or static members, since such things don't exist in C and would have to be left out of any C-compatible definition of the structure.
What about the derived class?
You couldn't define that class in a C program, so it couldn't do anything interesting with the pointer.
Maybe it can work for the base class. But that is on very special case:
But it will never directly for the derived class.
But that create so many restriction that I would provide a C level API to allocate an manipulate those pointers defined as alias on "void*" (I'm not even sure you can do such aliases this in pure C).
Something like:
typedef void* BaseStructPtr;
BaseStructPtr AllocateBase(/* constructor params */);
BaseStructPtr AllocateDerived(/* constructor params */);
TypeOfField1 GetField1(BaseStructPtr ptr);
TypeOfField2 GetField2(BaseStructPtr ptr);
/* etc... */
In your sample yes a C compiler will be able to use the Base_Struct* pointer and access members. You can use the same struct definition in C and CPP files without problems. As long as it's the Cpp who cast the struct for the C file the compiler will do the job.
void Give_Typed_Pointer_to_C_Function(Base_Struct* pStruct) {...}
void Give_Pointer_to_C_Function(void* pStruct) {...}
Base_Struct A;
Derived B;
Give_Typed_Pointer_to_C_Function(&A); // OK
Give_Typed_Pointer_to_C_Function(&B); // OK
Give_Pointer_to_C_Function(&A); // OK
Give_Pointer_to_C_Function(&B); // wrong
Give_Pointer_to_C_Function((Base_Struct*)&B); // OK
For this to work you have to use the same alignment and packing of struct but as you pass pointer I suppose you are same project so it should be already be the case.
You can even do more, if you keep struct in same order
struct S1 { int x;
int y;
};
class C1 { int x;
int y;
int add(int,int);
};
void Give_Typed_Pointer_to_C_Function(S1 *pStruct);
C1 object;
Give_Typed_Pointer_to_C_Function((S1*)&object); // OK
// an safer alternative as you can't have to be sure that S1 and C1 match
struct C1 { int x;
int y;
#ifdef __cplusplus
int add(int,int);
#endif
};
If you put Cpp keyword like class/public/private and methods in struct with defines. And if you don't use inheritance it will work as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With