Designing an API in C++

S

Sruli

Hi C++ gurus,

I'm developing a software product with a C++ API.
My concern is how to design the API so that future versions of the API
will be binary compatible with applications that use the older API
version.

E.g., suppose a customer application calls version 1 of the API. I
develop version 2, which has more public methods and variables. How can
I make sure that the old application works properly with the new API
version, without forcing the customer to recompile the appl?

The API should work on Windows + Unix, so I cannot use COM to resolve
this problem.

Any ideas would be welcome.

Sruli Ganor
 
I

Ivan Vecerina

: I'm developing a software product with a C++ API.
: My concern is how to design the API so that future versions of the API
: will be binary compatible with applications that use the older API
: version.
:
: E.g., suppose a customer application calls version 1 of the API. I
: develop version 2, which has more public methods and variables. How can
: I make sure that the old application works properly with the new API
: version, without forcing the customer to recompile the appl?
:
: The API should work on Windows + Unix, so I cannot use COM to resolve
: this problem.


The C++ language is well specified at the source code level,
but the object code is totally up to the implementation.

One issue is that class layout could change from release to
release of your libraries.
Another one is that on some platforms (notably x86), some
compilers do not use the same ABI (e.g. implementation and layout
of virtual functions, name mangling, exceptions, etc)
[ => incompatibility of Borland C++ and VC++ ].
Last but not least, on almost every platform, different compilers
(and even consecutive releases of the same development environment)
use implementations of the C++ standard library that differ
in class layout: so unless the exact same tool chain is used,
you cannot use std::string or any container/iterator in your
interface.
So if you distribute your library in binary form,
prepare for a serious challenge...

Very few (large) C++ libraries are distributed in binary form.
The famed BeOS is a notable exception. But Be controlled the
platform (defined ABI and library). Yet it had to use special
tricks to allow for future extensions (such as adding dummy
unused virtual functions to work around the Fragile Base Class
issue).


In my previous job I was developing high-level interface libraries
for haptic devices (www.xitact.com). Although everything was
developed in C++, I have pushed for providing a pure C interface
( within #ifdef __cplusplus extern "C" { #endif etc.
Implement opaque object handles that are internally converted
to a class instance to which calls are forwarded within
a try...catch(...) clause ).
This definitely was the right choice.

Initially, we did provide a C++ interface in source code form,
as a thin wrapper over our C-called interface DLL.
But our experience confirmed that different customers/developers
all wanted in any case to provide their own kind of wrapper
around our library, and would be encapsulating our interface
within their own C++ class in any case.
So they would end up going straight to the C api level.



If you really want to provide a C++ interface AND distribute
your library in binary form only, be prepared to re-compile
your library for every customer who will want to use it.
I wouldn't want to head in this direction.
And as a potential customer, I wouldn't tolerate such a level
of vendor-dependence either...


I hope this helps, Ivan
 
P

Peter

Sruli said:
Hi C++ gurus,

I'm developing a software product with a C++ API.
My concern is how to design the API so that future versions of the API
will be binary compatible with applications that use the older API
version.

E.g., suppose a customer application calls version 1 of the API. I
develop version 2, which has more public methods and variables. How can
I make sure that the old application works properly with the new API
version, without forcing the customer to recompile the appl?


by providing both, a new interface and the old one.

The API should work on Windows + Unix, so I cannot use COM to resolve
this problem.

Any ideas would be welcome.


in my experience the benefits of a C++ interface
(e.g. automatic memory management and C++ exceptions for error
conditions)
far outweight
the problems with a C++ interface.
On UNIX you can deliver your product together with the C++ compiler
used
(e.g. gnu-c++).
On Windows you can claim compatibility with Visual C++ VersionX.
 
S

Sruli

Ivan said:
Very few (large) C++ libraries are distributed in binary form.

Thanks for the detailed answer.
Let me narrow my question: suppose I develop a binary C++ API for
Windows in Visual C++, and require Windows customer to develop
application in this compiler only. I guess that this API should work on
any Windows platform.

My problem now is how to keep API working if I change it. E.g., I may
want to provide a new version of the API, with additional public
methods and variables.
Assuming that there is a customer application out there working wite
the previous version, is there a way to ensure that this application
will work with the new API version?
(I stress again that the compiler and platform were not changed).

Thanks in advance

Sruli Ganor
 
?

=?iso-8859-1?q?Kirit_S=E6lensminde?=

Sruli said:
Assuming that there is a customer application out there working wite
the previous version, is there a way to ensure that this application
will work with the new API version?

It's pretty simple. Give the new API a new DLL name and all will be
fine.

You'll be changing the object layouts so any applications will need to
be recompiled against the new headers etc. to work with the new DLL.
The easiest way to do this is to give the DLL a name based on the
version number. This is what Microsoft does too - look at the different
MSVCRT DLLs you have.

I suspect that this is going OT for this group though.


K
 
S

Sruli

Kirit said:
You'll be changing the object layouts so any applications will need to
be recompiled against the new headers etc. to work with the new DLL.

This is exactly my question. How can I provide an API DLL that does not
force the customer to recompile anything?

E.g., Version 1 of my API has one public method X.
Then I develop version 2 with public method X (old) and Y (new).
I want the old applications, that were compiled with version 1, to
continue working with the new DLL (version 2) without recomiping
anything, assuming that they still call X and don't have to call Y.

Is this posible?

Sruli
 
S

Sruli

Marcus said:
Substitute *your* version of Visual C++ for 'X'.

But my question is not about changing VisualC++ version, but changing
my API.

E.g., Version 1 of my API has one public method X.
Then I develop version 2 with public method X (old) and Y (new).
I want the old applications, that were compiled with version 1, to
continue working with the new DLL (version 2) without recomiping
anything, assuming that they still call X and don't have to call Y.

I asuume that the VisualC version is the same, both on my and the
customer's PC.


Is this posible?
 
P

Phlip

Sruli said:
This is exactly my question. How can I provide an API DLL that does
not force the customer to recompile anything?

Off-topic, if you need this level of pluggability, you need an ORB like
ActiveX or CORBA.

Without a system to define these interfaces pluggably, you are at the mercy
of your compiler. You might not even be able to change its settings without
recompiling.

But what's wrong with compiling everything when the API changes? Don't you
have automated build scripts??
 
?

=?iso-8859-1?q?Kirit_S=E6lensminde?=

Sruli said:
This is exactly my question. How can I provide an API DLL that does not
force the customer to recompile anything?

E.g., Version 1 of my API has one public method X.
Then I develop version 2 with public method X (old) and Y (new).
I want the old applications, that were compiled with version 1, to
continue working with the new DLL (version 2) without recomiping
anything, assuming that they still call X and don't have to call Y.


It may be possible to do this if the new API was only delivered through
derived classes and extensions. Then you could leave the first DLL
alone and provide the second version as a new DLL.

In practice this would be extremely difficult to do for most of the
sorts of changes that you would want to do. Many COM implementations go
down this route though as the COM interfaces are, well interfaces. So a
new interface is made, derived from the earlier one, and they are both
then supported by the new object.

It doesn't work so well in C++ as you have classes derived from other
classes and this causes a mess. You may be able to manage it if you can
implement your entire API as only abstract classes with factories that
create the instances from hidden concrete classes, but then you
probably should be going down the COM route to start with.


K
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top