[ACCEPTED]-How can I use Standard Library (STL) classes in my dll interface or ABI?-std

Accepted answer
Score: 97

Keep in mind one thing before you read further: My 76 answer is coming from the point of view 75 of writing portable code that can be used 74 in applications made up of modules compiled 73 under different compilers. This can include 72 different versions or even different patch 71 levels of the same compiler.

How can I use 70 stl-classes in my dll-interface?

Answer: You 69 often can't1.

Reason: The STL is a code library, not 68 a binary library like a DLL. It does not 67 have a single ABI that is guaranteed to 66 be the same wherever you might use it. Indeed, STL 65 does stand for "Standard Template Library," but 64 a key operative word here besides Standard 63 is Template.

The Standard defines the methods and 62 data members each STL class is required 61 to provide, and it defines what those methods 60 are to do; but no more. In particular, the 59 Standard doesn't specify how compiler writers 58 should implement the Standard-defined functionality. Compiler 57 writers are free to provide a implementation 56 of an STL class that adds member functions 55 and member variables not listed in the Standard, so 54 long as those members which are defined in 53 the Standard are still there and do what 52 the Standard says.

Maybe an example is in 51 order. The basic_string class is defined in the Standard 50 as having certain member functions & variables. The 49 actual definition is almost 4 pages in the 48 Standard, but here's just a snippet of it:

namespace std {
  template<class charT, class traits = char_traits<charT>,
    class Allocator = allocator<charT> >
  class basic_string {
[snip]
  public:
    // 21.3.3 capacity:
    size_type size() const;
    size_type length() const;
    size_type max_size() const;
    void resize(size_type n, charT c);
    void resize(size_type n);
    size_type capacity() const;
    void reserve(size_type res_arg = 0);
    void clear();
    bool empty() const;
[snip]
};

Consider 47 the size() and length() member functions. There is nothing 46 in the Standard that specified member variables 45 for holding this information. Indeed, there 44 are no member variables defined at all, not 43 even to hold the string itself. So how 42 is this implemented?

The answer is, many 41 different ways. Some compilers might use 40 a size_t member variable to hold the size and 39 a char* to hold the string. Another one might 38 use a pointer to some other data store which 37 holds that data (this might be the case 36 in a reference-counted implementation). In 35 fact, different versions or even patch levels of the 34 same compiler may change these implementation 33 details. You can't rely on them. So, MSVC 32 10's implementation might look like this:

namespace std {
  template<class charT, class traits = char_traits<charT>,
    class Allocator = allocator<charT> >
  class basic_string {
[snip]
char* m_pTheString;
};

size_t basic_string::size() const { return strlen(m_pTheString;) }

...Whereas 31 MSVC 10 with SP1 might look like this:

namespace std {
  template<class charT, class traits = char_traits<charT>,
    class Allocator = allocator<charT> >
  class basic_string {
[snip]
vector<char> m_TheString;
};

size_t basic_string::size() const { return m_TheString.size(); }

I'm 30 not saying they do look like this, I'm saying 29 they might. The point here is the actual 28 implementation is platform-dependent, and 27 you really have no way of knowing what it 26 will be anywhere else.

Now say you use MSVC10 25 to write a DLL that exports this class:

class MyGizmo
{
public:
  std::string name_;
};

What 24 is the sizeof(MyGizmo)?

Assuming my proposed implementations 23 above, under MSVC10 its going to be sizeof(char*), but 22 under SP1 it will be sizeof(vector<char>). If you write an 21 application in VC10 SP1 that uses the DLL, the 20 size of the object will look different than 19 it actually is. The binary interface is 18 changed.


For another treatment of this, please 17 see C++ Coding Standards (Amazon link) issue # 63.


1: "You often can't" You 16 actually can export Standard Library components 15 or any other code library components (such 14 as Boost) with a fair amount of reliability 13 when you have complete control over the 12 toolchains and the libraries.

The fundamental 11 problem is that with source code libraries 10 the sizes and definitions of things can 9 be different between different compilers 8 and different versions of the library. If 7 you are working in an environment where 6 you control both of these things everywhere 5 your code is used, then you probably won't 4 have a problem. For example at a trading 3 firm where all the systems are written in-house 2 and used only in-house, it might be possible 1 to do this.

More Related questions