Is there any tips one can give me about passing pointers to structs, doubles, functions, ... from a C program to a C++ library and back?
C and C++ pointers are the same -- a pointer is basically pointing to a block of memory, and that does not change going from C/C++.
You do want to be careful about not crossing heap types -- for instance, don't allocate in one library and de-allocate in a library that might have another heap or be using another runtime version (or vice versa).
Did you mean to ask about issues around pass-by-value or pass-by-reference? It might help to provide a more concrete question.
- dont forget the extern "C" keyword to avoid problem with the C++ mangling name.
- Dont use pass by reference argument type but pointer
Assuming you're coding these in two different libraries static or dynamic (DLLs on windows shared libraries on Linux and other *nix variants) The biggest concerns I have are as follows:
They are compiled with the same compiler. While this isn't necessary if all C++ exports are exported with a C-style naming convention it is necessary for C++ to C++ calls to class instances between the two C++ modules. This is necessary due to how different compilers mangle C++ exports differently.
Do not cast a C++ class as a C struct. They aren't the same under the covers, even if the layout of fields are the same. C++ classes have a "v-table" if they have any virtual members; this v-table allows the proper calling of inherited or base class methods.
This is true of C to C or C++ to C++ as well as C to C++. Ensure both use the same byte alignment for the output library. You can only determine this by reading your compiler or development environments documentation.
Don't mix malloc/free with new/delete. More specifically don't allocate memory with new and free memory with "free" and vice versa. Many compilers and operating systems handle memory management differently between the two.
Passing function pointers: So long as they are exposed to/from C++ as ''extern "C"'' this should be fine. (You'll either need to reference your compilers documentation on how to determine when a header is being compiled as C or C++ to maintain this in one file, or you will need two separate copies of the same function declaration in each project -- I recommend the first)
Passing doubles: These are an integral type to both C and C++ and should be handled the same.
If you must share an instance of a C++ object with a C function, and act on it from within C code, expose a set of C-exported helper functions which call the appropriate methods on the C++ object. Pure C code cannot properly call methods on C++ objects.
Pseudocode-ish Example:
// C++ class
class foo {
public:
void DoIt();
};
// export helper declarations
extern "C" void call_doit(foo* pFoo);
extern "C" foo* allocate_foo();
extern "C" deallocate_foo(foo* pFoo);
// implementation
void call_doit(foo* pFoo)
{
pFoo->DoIt();
}
foo* allocate_foo()
{
return new foo();
}
deallocate_foo(foo* pFoo)
{
delete pFoo;
}
// c consumer
void main()
{
foo* pFoo= allocate_foo();
call_doit(pFoo);
dealocate_foo(pFoo);
}