views:

69

answers:

3

I need to develop a C++ front-end GUI using MSVC that needs to communicate with the bank-end library that is compiled with C++ Builder.

How can we define our interfaces so that we don't run into CRT library problems?

For example, I believe we will be unable to safely pass STL containers back and forth. Is that true?

I know I can pass POD types safely, but I am hoping that I can use some more sophisticated data structures as well.

+2  A: 

You should be able to pass data that you can safely pass via a C interface, in other words, PODs. Everything over and above PODs that is being passed by regular C or C++ function calls will run into issues with differing object layouts and different implementations of the runtime libraries.

You probably will be able to pass structs of PODs if you are very careful about how you lay them out in memory and ensure that both compilers are using the same data packing etc. Over and above C structs, you pretty much have a creek/paddle problem.

For passing more sophisticated data types, I would look into object component technologies like COM, CORBA or other technologies that allow you to make remote or cross-process function calls. These would solve the problem of marshalling the data between compilers and processes and thus solve your 'pod-only' problem.

Or you could write the front end using C++-Builder and save yourself a lot of grief and headaches.

Timo Geusch
+1  A: 

I ran into problems when passing STL-Containers even when using the same STL-Implementation, but having set different levels of debug information etc. Therefore Passing PODs will be OK. C++ Containers will almost certainly result in problems.

RED SOFT ADAIR
+4  A: 

You might find this article interesting Binary-compatible C++ Interfaces. The lesson in general is, never pass STL container, boost or anything of the like. Like the two other answers your best bet is to stick with PODs and functions with a calling convention specified.

Since implementations of the STL vary from compiler to compiler, it is not safe to pass STL classes. You can then either require the user to a specific implementation of the STL (and probably a specific version as well), or simply not use the STL between libraries.

Further more stick with the calling conventions where the behaviour can be considered cross compiler frieindly. For instance __cdecl and __stdcall will be handled equally on most compilers, while the __fastcall calling convention will be a problem, especially if you wish to use the code in C++ Builder.

As the article "Binary-compatible C++ Interface" mentions you can use interface as well, as long as you remember a few basic principles.

  1. Always make interfaces pure virtual classes (that is no implementations).
  2. Make sure to use a proper calling convention for the member functions in the interface (the article mentions __stdcall for Windows.
  3. Keep the memory clean up at the same side of the DLL boundary.
  4. And quite a few other things, like don't use exceptions, don't overload functions in the interface (compilers treat this differently), etc. Find them all at the bottom of the article.

You might want to read more about the Component Object Model (COM) if you choose to go with the C++ interfaces, to get an idea about how and why this will be able to work across compilers.

TommyA
Tobias Langner