I have a set of related C++ classes which must be wrapped and exported from a DLL in such a way that it can be easily consumed by C / FFI libraries. I'm looking for some "best practices" for doing this. For example, how to create and free objects, how to handle base classes, alternative solutions, etc...
Some basic guidelines I have so far is to convert methods into simple functions with an extra void* argument representing the 'this' pointer, including any destructors. Constructors can retain their original argument list, but must return a pointer representing the object. All memory should be handled via the same set of process-wide allocation and free routines, and should be hot-swappable in a sense, either via macros or otherwise.
Yes - C++ can use C libraries. Except of course that you're using the C++ version of cstdio . To use the C one you need to #include <stdio. h> .
C and C++ are two closely related programming languages. Therefore, it may not come as a surprise to you that you can actually mix C and C++ code in a single program. However, this doesn't come automatically when you write your code the normal way.
C language API. The C language Application Programmer's Interface (API) allows application programs to submit faxes to the Zetafax server for sending, and to control and monitor their progress as required. A simple function call is provided to submit an ASCII text file in a given format.
Foreach public method you need a C function.
You also need an opaque pointer to represent your class in the C code.
It is simpler to just use a void* though you could build a struct that contains a void* and other information (For example if you wanted to support arrays?).
Fred.h -------------------------------- #ifdef __cplusplus class Fred { public: Fred(int x,int y); int doStuff(int p); }; #endif // // C Interface. typedef void* CFred; // // Need an explicit constructor and destructor. extern "C" CFred newCFred(int x,int y); extern "C" void delCFred(CFred); // // Each public method. Takes an opaque reference to the object // that was returned from the above constructor plus the methods parameters. extern "C" int doStuffCFred(CFred,int p);
The the implementation is trivial.
Convert the opaque pointer to a Fred and then call the method.
CFred.cpp -------------------------------- // Functions implemented in a cpp file. // But note that they were declared above as extern "C" this gives them // C linkage and thus are available from a C lib. CFred newCFred(int x,int y) { return reinterpret_cast<void*>(new Fred(x,y)); } void delCFred(CFred fred) { delete reinterpret_cast<Fred*>(fred); } int doStuffCFred(CFred fred,int p) { return reinterpret_cast<Fred*>(fred)->doStuff(p); }
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