FAQ 36.05 How can an object of a C++ class be passed to or from a C function?With a layer of glue code. The example that follows is a bilingual header file, readable by both a straight C compiler and a C++ compiler. Bilingual header files often use the preprocessor symbol __cplusplus, which is automatically #defined by C++ compilers but left undefined by C compilers. /****** Bilingual C/C++ header file: Fred.h ******/ #ifdef __cplusplus class Fred { public: Fred() throw(); void wilma(int i) throw(); protected: int i_; }; inline Fred::Fred() throw() : i_(0) { } inline void Fred::wilma(int i) throw() { i_ = i; } #else struct Fred { int i_; }; typedef struct Fred Fred; #endif #ifdef __cplusplus extern "C" { #endif extern void cppCallingC(Fred* p); extern void cCallingCpp(Fred* p, int param); #ifdef __cplusplus } #endif The function cCallingCpp() might be defined in a C++ file, such as c++-code.cpp. // This is C++ code #include "Fred.h" void cCallingCpp(Fred* p, int param) throw() { p->wilma(param); } The function cppCallingC() might be defined in a C file, such as c-code.c. /* This is C code */ #include "Fred.h" void cppCallingC(Fred* p) { cCallingCpp(p, 3); } A Fred might be passed to the C code by main() (recall that main() must be compiled by the C++ compiler). // This is C++ code #include "Fred.h" int main() { Fred x; cppCallingC(&x); } Note that C code should not cast pointers that refer to C++ objects because doing so can introduce errors, especially in cases where the pointer is returned to C++. For example, most compilers adjust the pointer during certain pointer casts involving multiple and/or virtual inheritance; the C compiler doesn't know how to do these adjustments. The example assumes that the C compiler supports ANSI-C function prototypes. Use #ifdef __STDC__ for those rare legacy situations that require selecting code that supports only the outdated K&R C style. |