News:

This week IPhone 15 Pro winner is karn
You can be too a winner! Become the top poster of the week and win valuable prizes.  More details are You are not allowed to view links. Register or Login 

Main Menu

Interfacing a C++ library to C

Started by ben2ong2, October 06, 2006, 10:56:54 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ben2ong2

PROBLEM: You are not allowed to view links. Register or Login (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?



* 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: You are not allowed to view links. Register or Login (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!

   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.


You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login