STL and shared libraries

S

Steve

Hi,

We have an application framework library that gets statically linked to any
applications we produce. (Windows apps, but I don't think that matters
here).

The framework is based heavily on the STL and the API uses many STL
constructs. Because of the static linking, and the fact that both app and
framework are built by the same compiler, we don't have any problems.

Now somebody has suggested we make the framework a shared library.

Of course, this probably means a big re-write is on the cards, and I am
aware that there can be issues if std::strings and other STL templated
classes are exposed on a shared library API.

Has anyone here had to tackle this problem? Any advice would be most
welcome. (Is there a common design pattern one could follow?)

I guess this is the reason why C++ libraries like QT and xerces provide
their OWN classes instead of using STL, right? :)

Thanks.

--
Regards,
Steve

"...which means he created the heaven and the earth... in the DARK! How good
is that?"
 
B

Bob Hairgrove

Hi,

We have an application framework library that gets statically linked to any
applications we produce. (Windows apps, but I don't think that matters
here).

The framework is based heavily on the STL and the API uses many STL
constructs. Because of the static linking, and the fact that both app and
framework are built by the same compiler, we don't have any problems.

Now somebody has suggested we make the framework a shared library.

Of course, this probably means a big re-write is on the cards, and I am
aware that there can be issues if std::strings and other STL templated
classes are exposed on a shared library API.

Has anyone here had to tackle this problem? Any advice would be most
welcome. (Is there a common design pattern one could follow?)

I guess this is the reason why C++ libraries like QT and xerces provide
their OWN classes instead of using STL, right? :)

Thanks.

As long as you keep to the same environment (i.e. same compiler, etc.)
there's nothing inherent about the STL which would preclude making a
shared library with components which use it, as long as the clients
using the shared library are also compiled with the same compiler.

It all depends on how it is used, of course. You have to be
particularly careful with memory management issues when using shared
libraries, i.e. creating an object with "new" in one module and
destroying it with "delete" in a different module is definitely
something to avoid. The only way this can possibly work is if ALL
executables and libraries involved use the same C runtime library. And
the only way this would work is to link the CRT dynamically.

A good (and important) design pattern for this problem is the
"abstract factory". You would typically do the creation and
destruction of objects in the same factory class, exposing
Factory::Create() and Factory::Destroy() functions, instead of relying
on the clients to call new and delete.
 
S

Steve

As long as you keep to the same environment (i.e. same compiler, etc.)
there's nothing inherent about the STL which would preclude making a
shared library with components which use it, as long as the clients
using the shared library are also compiled with the same compiler.

That¹s what I thought, but I have a wild aspiration to possibly license our
framework to existing clients. In that case, we can't really rely on them
using a specific compiler. (Perhaps it's far too wild!)
It all depends on how it is used, of course. You have to be
particularly careful with memory management issues when using shared
libraries, i.e. creating an object with "new" in one module and
destroying it with "delete" in a different module is definitely
something to avoid. The only way this can possibly work is if ALL
executables and libraries involved use the same C runtime library. And
the only way this would work is to link the CRT dynamically.

Absolutely. And I have been bitten with this before. Once bitten, and all
that!
A good (and important) design pattern for this problem is the
"abstract factory". You would typically do the creation and
destruction of objects in the same factory class, exposing
Factory::Create() and Factory::Destroy() functions, instead of relying
on the clients to call new and delete.

Nice idea. And by making making constructors private, I can ensure the user
will always need to call the Create and Destroy methods?


Thanks very much.

--
Regards,
Steve

"...which means he created the heaven and the earth... in the DARK! How good
is that?"
 
I

Ian

Steve said:
Hi,

We have an application framework library that gets statically linked to any
applications we produce. (Windows apps, but I don't think that matters
here).

The framework is based heavily on the STL and the API uses many STL
constructs. Because of the static linking, and the fact that both app and
framework are built by the same compiler, we don't have any problems.

Now somebody has suggested we make the framework a shared library.

Of course, this probably means a big re-write is on the cards, and I am
aware that there can be issues if std::strings and other STL templated
classes are exposed on a shared library API.
What C++ (rather than platform) issues do you foresee?
Has anyone here had to tackle this problem? Any advice would be most
welcome. (Is there a common design pattern one could follow?)
Many times and I've never had any issues.
I guess this is the reason why C++ libraries like QT and xerces provide
their OWN classes instead of using STL, right? :)
No, they just pre-date the standard library.

Ian
 
V

Valentin Samko

Steve said:
We have an application framework library that gets statically linked to any
applications we produce. (Windows apps, but I don't think that matters
here).

The framework is based heavily on the STL and the API uses many STL
constructs. Because of the static linking, and the fact that both app and
framework are built by the same compiler, we don't have any problems.

Now somebody has suggested we make the framework a shared library.

Of course, this probably means a big re-write is on the cards, and I am
aware that there can be issues if std::strings and other STL templated
classes are exposed on a shared library API.

The most simple approach is to link to the dynamic CRT library. This way you will only
have one heap, and this would save you from allocating in one heap (in main application)
and freeing in another heap (in your shared library), or vice verse.
Has anyone here had to tackle this problem? Any advice would be most
welcome. (Is there a common design pattern one could follow?)
Another thing you must be aware of is the problem of "multiple singletons". If you have a
header file with something like
template<class T> struct A { static MySingleton singleton; };
MySingleton A::singleton;
and you include this header file both, in your shared library and in your main executable,
then you will get two instances of this singleton, one in the shared library, and another
one in the main executable. This wouldn't happen if you had a static library.
I guess this is the reason why C++ libraries like QT and xerces provide
their OWN classes instead of using STL, right? :)
No. They were written before the standard came out. Actually, afaik QT 4.0 uses STL.
 
S

Steve

What C++ (rather than platform) issues do you foresee?

The implementation of std::string [as one example] might be, or, is probably
different between compilers - for example, GCC and Visual Studio.

Say the library was compiled with Visual Studio, then the API was used
within a gcc-compiled application, and the API had the following function:

void DoSomething( const std::string& );

GCC would pass a reference to it's own std::string object. The
implementation of the function (compiled under Visual Studio) is still
expecting a std::string, but its internals are likely to be completely
different.
Many times and I've never had any issues.

But are the libraries built with one compiler, then used in an application
built with a different one?

As I said in my reply to Bob Hairgrove, this may be just a wild aspiration I
have. I could probably live without this requirement for now!
No, they just pre-date the standard library.

Are you sure? I can't confirm QT, but the initial beta release of xerces was
in November 1999.

--
Regards,
Steve

"...which means he created the heaven and the earth... in the DARK! How good
is that?"
 
I

Ian

Steve said:
What C++ (rather than platform) issues do you foresee?


The implementation of std::string [as one example] might be, or, is probably
different between compilers - for example, GCC and Visual Studio.

Say the library was compiled with Visual Studio, then the API was used
within a gcc-compiled application, and the API had the following function:

void DoSomething( const std::string& );

GCC would pass a reference to it's own std::string object. The
implementation of the function (compiled under Visual Studio) is still
expecting a std::string, but its internals are likely to be completely
different.
Ah, I missed you point. No, you cant mix C++ objects or libraries built
with different compilers. Unless you only interface through extern "C"
functions.

Are you sure? I can't confirm QT, but the initial beta release of xerces was
in November 1999.
Wasn't xerces an internal IBM project way before it was part of Apache?

Ian
 
V

Valentin Samko

Ian said:
Ah, I missed you point. No, you cant mix C++ objects or libraries built
with different compilers. Unless you only interface through extern "C"
functions.

Moreover, you can not mix objects built with the same compiler but when optimisation
settings differ in specific ways, and this is compiler dependent. The first problem would
be padding of class data members.
 

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,770
Messages
2,569,584
Members
45,078
Latest member
MakersCBDBlood

Latest Threads

Top