TITLE: Interfacing a C++ library to C PROBLEM: harvey@kc-10.jsc.nasa.gov (Kyle Harvey), 22 Apr 93 I'm trying to create a library of functions that are written in C++, yet are callable from C. I think this can be done because I've heard that SGI's Inventor product uses a similar strategy. I'm trying to let C maintain pointers to my C++ class instances by casting them to void pointers. This seems to work, but when I run my tests, my constructors are called, but not my destructors. [a] * Am I out of line in even thinking this should work? [b] * How can I implement C++ libraries that are callable from C? [c] * Is there a better way to let C hang on to my C++ class instances than through void pointers? RESPONSE: maxtal@physics.su.OZ.AU (John Max Skaller), 22 Apr 93 [a] It can work .. but not automatically: in C you have to call the destructors explicitly. The choice of void* is the worst possible choice. DONT! [b] You need to write an interface module(s). [c] Wrong question. Could there possibly be a worse way? There are many methods, but I suggest something like this: On the C side: struct Circle { void* data; int checksum; }; The checksum is there to validate the pointer has been initialised properly (and not destroyed). It is not an iron cast assurance, but it catches quite a few errors. Next, you need to provide routines like: Circle CircleCreate( .. data .. ) void CircleDestroy(Circle); If your class is an ADT you might also supply: Circle CircleCopy(Circle); Circle CircleAssign(Circle, Circle); whereas if its an Object you wont. You will of course provide routines like: void CircleDraw(Circle); All these things are statically checked in ANSI C. Except for Create, the checksum is checked. Destroy also zaps it. This system is still not safe. You can improve it by storing an 'object number' in each C++ object in a fixed place, and also in the C struct. Then you can compare the numbers after casting the void* which will catch a few more errors. Make sure the destructor of the C++ object zaps the object number. The system I have described provides some security. You can have 100% security by keeping a list of all the live objects and just checking the C void* is in the list. With suitable techniques and modest object populations this can be reasonably fast I think: for large ensembles of objects the overheads will be too great. I'm sure there are other techniques, but this one is simple and gives a reasonable probability of catching errors. In fact, its safer standard C++ techniques using pointers.