HOWTO: Exporting STL Components Inside & Outside of a ClassLast reviewed: January 19, 1998Article ID: Q168958 |
The information in this article applies to:
SUMMARYThis article demonstrates how to:
MORE INFORMATIONBeginning with Visual C++ 5.0, it is possible to force an instantiation of a template class and export the instantiation. To export a template class instantiation, use the following syntax:
To Export an STL Class
To Export a Class Containing a Data Member that is an STL Object
Some STL classes contain nested classes. These classes cannot be exported. For instance, deque contains a nested class deque::iterator. If you export deque, you will get a warning that you must export deque::iterator. If you export deque::iterator, you get a warning that you must export deque. This is caused by a designed limitation that once a template class is instantiated, it cannot be re-instantiated and exported. Because of this limitation, make sure that you export your instantiations of the template classes before they are instantiated by any other code. When you export an STL container parameterized with a user-defined type (UDT), you must define the operators < and == for your UDT. For example, if you export vector<MyClass>, you must define MyClass::operator < and MyClass operator ==. This is because all STL container classes have member comparison operators that require the existence of the operators < and == for the contained type. Normally, these are not instantiated because they are not used. When you instantiate an instance of a template class, all member functions are generated. Since the STL container classes have member functions that use the operators < and == for the contained type, you must implement them. If comparing objects of your UDT does not make sense, you can define the comparison operators to simply return “true.” When the symbol _DLL is defined during compiling (this symbol is implicitly defined when compiling with /MD or /MDd to link with the DLL version of the C Runtime), the following STL classes, and various global operators and functions that operate on these classes, are already exported by the C Runtime DLL. Therefore, you cannot export them from your DLL. This should not cause a problem for the executable program that imports your class as long as it also uses the DLL version of the C Runtime:
Header STL template class ------ ------------------ <IOSFWD> basic_ios <IOSFWD> basic_streambuf <IOSFWD> basic_istream <IOSFWD> basic_string (also typedef'd as string and wstring) <IOSFWD> complex <LOCALE> messages <XLOCALE> codecvt <XLOCALE> ctype <XLOCMON> moneypunct <XLOCMON> money_get <XLOCMON> money_put <XLOCNUM> numpunct<XLOCTIME> time_get <XLOCTIME> time_put <XSTRING> basic_string (also typedef'd as string and wstring)For specific details on which template parameters are used and which global functions and operators are declared, please see the relevant header file.
Sample Code
// ------------------------------------------- // MYHEADER.H //disable warnings on 255 char debug symbols #pragma warning (disable : 4786) //disable warnings on extern before template instantiation #pragma warning (disable : 4231) #include <vector> // Provide the storage class specifier (extern for an .exe file, null // for DLL) and the __declspec specifier (dllimport for .an .exe file, // dllexport for DLL). // You must define EXP_STL when compiling the DLL. // You can now use this header file in both the .exe file and DLL - a // much safer means of using common declarations than two different // header files. #ifdef EXP_STL # define DECLSPECIFIER __declspec(dllexport) # define EXPIMP_TEMPLATE #else # define DECLSPECIFIER __declspec(dllimport) # define EXPIMP_TEMPLATE extern #endif // Instantiate classes vector<int> and vector<char> // This does not create an object. It only forces the generation of all // of the members of classes vector<int> and vector<char>. It exports // them from the DLL and imports them into the .exe file. EXPIMP_TEMPLATE template class DECLSPECIFIER std::vector<int>; EXPIMP_TEMPLATE template class DECLSPECIFIER std::vector<char>; // Declare/Define a class that contains both a static and non-static // data member of an STL object. // Note that the two template instantiations above are required for // the data members to be accessible. If the instantiations above are // omitted, you may experience an access violation. // Note that since you are exporting a vector of MyClass, you must // provide implementations for the operator < and the operator ==. class DECLSPECIFIER MyClass { public: std::vector<int> VectorOfInts; static std::vector<char> StaticVectorOfChars; public: bool operator < (const MyClass & c) const { return VectorOfInts < c. VectorOfInts; } bool operator == (const MyClass & c) const { return VectorOfInts == c. VectorOfInts; } }; // Instantiate the class vector<MyClass> // This does not create an object. It only forces the generation of // all of the members of the class vector<MyClass>. It exports them // from the DLL and imports them into the .exe file. EXPIMP_TEMPLATE template class DECLSPECIFIER std::vector<MyClass>; // ------------------------------------------- // Compile options needed: /GX /LDd /MDd /D"EXP_STL" // or: /GX /LD /MD /D"EXP_STL" // DLL.CPP #include "MyHeader.h" std::vector<char> MyClass::StaticVectorOfChars; // ------------------------------------------- // Compile options needed: /GX /MDd // or: /GX /MD // EXE.CPP #include <iostream> #include "MyHeader.h" int main () { MyClass x; for (int i=0; i<5; i++) x.VectorOfInts.push_back(i); for (char j=0; j<5; j++) x.StaticVectorOfChars.push_back('a' + j); std::vector<int>::iterator vii = x.VectorOfInts.begin(); while (vii != x.VectorOfInts.end()) { std::cout << *vii; std::cout << " displayed from x.VectorOfInts" << std::endl; vii++; } std::vector<char>::iterator vci = x.StaticVectorOfChars.begin(); while (vci != x.StaticVectorOfChars.end()) { std::cout << *vci; std::cout << " displayed from MyClass::StaticVectorOfChars"; std::cout << std::endl; vci++; } std::vector<MyClass> vy; for (i=0; i=5; I++) vy.push_back(MyClass()); return 1; } REFERENCESTITLE: Explicit Instantiation URL: mk:@ivt:vclang/FB/DD/S44AE7.HTMTITLE: __declspec URL: mk:@ivt:vccore/F3C/D3E/S4C390.HTMTITLE: stack URL: mk:@ivt:vclang/STDLIBBLD/STACK_STACK.HTMTITLE: /MD, /ML, /MT, /LD (Use Run-Time Library) URL: mk:@ivt:vccore/F19/D1E/S4D030.HTM Keywords : STLIss kbcode Version : WINNT:5.0; Platform : winnt Issue type : kbhowto |
================================================================================
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |