Cómo exportar una instancia de una clase de biblioteca de plantillas estándar (STL) y una clase que contiene a un miembro de datos que es un objeto STL

IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.

Haga clic aquí para ver el artículo original (en inglés): 168958
Este artículo se ha archivado. Se ofrece "tal cual" y no se volverá a actualizar.
Resumen
En este artículo se explica cómo realizar las siguientes tareas:
  • Exportar una instancia de una biblioteca de plantillas estándar (STL) de clase.
  • Exportar una clase que contiene un miembro de datos que es un STL objeto.
Tenga en cuenta que no puede exportar un plantilla generalizado. La plantilla debe crearse; es decir, todos los parámetros de plantilla se deben proporcionar y deben ser tipos completamente definidos en el momento de creación de instancias. Para la instancia "pila <int>;" crea la clase de pila STL. La creación de instancias obliga a todos los miembros de clase de pila <int> generarse.

Observe también que no pueden exportarse algunos contenedores STL (mapa de conjunto, cola, lista, deque). Consulte la sección más información para seguir para obtener una explicación detallada.
Más información
A partir de Visual C++ 5.0, es posible forzar una instancia de una clase de plantilla y exportar la creación de instancias. Para exportar una instancia de clase de plantilla, utilice la sintaxis siguiente:

Para exportar una clase STL

  1. En el archivo DLL y el archivo .exe, vincular con la misma DLL versión de la C en tiempo de ejecución. Puede vincular ambos con MSVCRT.lib (lanzamiento), o vincular ambos con msvcrtd.lib (compilación de depuración).
  2. En el archivo DLL, proporcione el especificador de __declspec en la declaración de creación de instancias de plantilla para exportar la creación de instancias de clase STL desde el archivo DLL.
  3. En el archivo .exe, proporcionan los especificadores de extern y __declspec en la declaración de creación de instancias de plantilla para importar la clase desde el archivo DLL. Esto da como resultado una advertencia C4231 "se ha utilizado una extensión no estándar: 'extern' antes de la creación de instancias explícita de plantilla." Puede omitir esta advertencia.

Para exportar una clase con un miembro de datos que es un objeto STL

  1. En el archivo DLL y el archivo .exe, vincular con la misma DLL versión de la C en tiempo de ejecución. Puede vincular ambos con MSVCRT.lib (lanzamiento), o vincular ambos con msvcrtd.lib (compilación de depuración).
  2. En el archivo DLL, proporcione el especificador de __declspec en la declaración de creación de instancias de plantilla para exportar la creación de instancias de clase STL desde el archivo DLL.

    Nota: No omita el paso 2. Debe exportar la instancia de la clase STL que utiliza para crear al miembro de datos.
  3. En el archivo DLL, proporcione el especificador de __declspec en la declaración de la clase para exportar la clase desde el archivo DLL.
  4. En el archivo .exe, proporcione el especificador de __declspec en la declaración de la clase para importar la clase desde el archivo DLL.

    Si la clase va a exportar tiene uno o más clases base, debe exportar las clases base. Si la clase que va a exportar contiene a miembros de datos que son del tipo de clase, debe exportar las clases de los miembros de datos así.
Nota: Algunas clases STL utilizan otras clases STL. También deben exportarse estas otras clases. Las clases que se deben exportar aparecen en las advertencias del compilador si compila con un nivel de advertencia inferior a 1; es decir, /W2, /W3 o/W4. Nivel de advertencia 4 no se recomienda actualmente por este motivo y genera mucha de mensajes de advertencia para los encabezados STL.

Algunas clases STL contienen clases anidadas. Estas clases no pueden exportarse. Por ejemplo, deque contiene una clase anidada deque::iterator. Si exporta deque, obtendrá una advertencia que debe exportar deque::iterator. Si exporta deque::iterator, obtendrá una advertencia que debe exportar deque. Esto se debe a una limitación diseñada que una vez que se crea una instancia de una clase de plantilla, puede no ser re-instantiated y exportar. El único contenedor STL que actualmente se puede exportar es vector. Los contenedores (es decir, mapa, conjunto, cola, lista, deque) todo contienen las clases anidadas y no se puede exportar.

Al exportar un contenedor STL parametrizado con un tipo definido por el usuario (UDT), debe definir los operadores < y == para los UDT. <myclass>Por ejemplo, si exporta vector < Miclase >, debe definir MyClass::operator < y MyClass operador ==. Esto es porque todas las clases de contenedor STL tienen miembro operadores de comparación que requieren la existencia de los operadores < y == para el tipo de contenido. Normalmente, estos no se crean instancias porque no se utilizan. Cuando crea una instancia de una clase de plantilla, se generan todas las funciones miembro. Dado que las clases de contenedor STL tienen funciones miembro que utilice los operadores < y == para que el tipo de contenido, las debe implementar. Si se comparan objetos de su tipo definido por el usuario no tiene sentido, puede definir los operadores de comparación para devolver simplemente "true".

Cuando se define el símbolo _DLL durante compilar (implícitamente este símbolo se define al compilar con /MD o /MDd vincular con la versión DLL de C Runtime), las siguientes clases STL y diversos globales operadores y funciones que operan sobre estas clases, ya se exportan por la DLL en tiempo de ejecución de C. Por lo tanto, no puede exportar ellos desde el archivo DLL. Esto no debería causar un problema del programa ejecutable que se importa la clase mientras utiliza también la versión DLL de la C en tiempo de ejecución:
Header      STL template class------------------------------<IOSFWD>    basic_ios<IOSFWD>    <IOSFWD><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)				
para los detalles específicos de los parámetros de plantilla que se utilizan y qué funciones globales y los operadores se declaran, por favor, vea el archivo de cabecera.

Código de ejemplo

   // -------------------------------------------   // 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;    }				
Referencias
Para obtener información adicional, busque los siguientes temas de Ayuda de Visual C++:
Creación de instancias explícita
__declspec
pila
/ MD, / ML, / MT, /ld (utilizar la biblioteca en tiempo de ejecución)

Advertencia: este artículo se tradujo automáticamente

Propiedades

Id. de artículo: 168958 - Última revisión: 12/04/2015 17:05:09 - Revisión: 3.0

Microsoft Visual C++ 5.0 Enterprise Edition, Microsoft Visual C++ 6.0 Enterprise, Microsoft Visual C++ 5.0 Professional, Microsoft Visual C++ 6.0 Professional, Microsoft Visual C++, 32-bit Learning Edition 6.0

  • kbnosurvey kbarchive kbmt kbstl kbinfo kbcode kbhowto KB168958 KbMtes
Comentarios