sirve que para metodos librerias las funcion estandar español definicion clases clase bibliotecas biblioteca c++ dll c++11 stl std

metodos - push c++ para que sirve



¿Cómo puedo usar las clases de Biblioteca estándar(STL) en mi interfaz dll o ABI? (1)

Ha habido algunas preguntas antes sobre la exportación de una clase que contiene clases stl en relación con el estudio visual de advertencia C4251: por ejemplo, esta pregunta o esta pregunta. Ya leí la excelente explicación en UnknownRoad.

Desactivar ciegamente la advertencia parece un poco peligroso, aunque puede ser una opción. Envolver todas esas clases estándar y exportarlas tampoco es realmente una opción. Después de todo, se llama Biblioteca de plantillas estándar ... Es decir, se desea proporcionar una interfaz con estas clases estándar.

¿Cómo puedo usar stl-classes en mi interfaz dll? ¿Cuáles son las prácticas comunes?


Tenga en cuenta una cosa antes de seguir leyendo: mi respuesta proviene del punto de vista de escribir código portátil que se puede usar en aplicaciones compuestas por módulos compilados en diferentes compiladores. Esto puede incluir diferentes versiones o incluso diferentes niveles de parche del mismo compilador.

¿Cómo puedo usar stl-classes en mi interfaz dll?

Respuesta: a menudo no puedes 1 .

Motivo: el STL es una biblioteca de códigos, no una biblioteca binaria como una DLL. No tiene un solo ABI que garantice ser el mismo donde sea que lo use. De hecho, STL representa "Biblioteca de plantillas estándar ", pero una palabra clave aquí además de Estándar es Plantilla .

El Estándar define los métodos y los miembros de los datos que debe proporcionar cada clase de STL, y define qué deben hacer esos métodos; pero no más. En particular, el Estándar no especifica cómo los escritores del compilador deberían implementar la funcionalidad definida por el estándar. Los escritores de compiladores pueden proporcionar una implementación de una clase STL que agregue funciones miembro y variables miembro no enumeradas en el Estándar, siempre y cuando los miembros definidos en el Estándar sigan allí y hagan lo que dice el Estándar.

Tal vez un ejemplo esté en orden. La clase basic_string se define en el estándar como que tiene ciertas funciones y variables miembro. La definición real es de casi 4 páginas en el Estándar, pero aquí hay solo un fragmento de ella:

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] };

Considere las funciones de los miembros size() y length() . No hay nada en el Estándar que especifique las variables miembro para contener esta información. De hecho, no hay variables miembro definidas en absoluto, ni siquiera para contener la cadena en sí. Entonces, ¿cómo se implementa esto?

La respuesta es, de muchas maneras diferentes. Algunos compiladores pueden usar una variable de miembro size_t para mantener el tamaño y un char* para contener la cadena. Otro podría usar un puntero a otro almacén de datos que contenga esa información (este podría ser el caso en una implementación contada por referencia). De hecho, las diferentes versiones o incluso los niveles de parche del mismo compilador pueden cambiar estos detalles de implementación. No puedes confiar en ellos. Entonces, la implementación de MSVC 10 podría verse así:

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;) }

... Mientras que MSVC 10 con SP1 podría verse así:

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(); }

No digo que se vean así, estoy diciendo que sí. El punto aquí es que la implementación real depende de la plataforma, y ​​realmente no tienes forma de saber qué será en otro lado.

Ahora diga que usa MSVC10 para escribir una DLL que exporta esta clase:

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

¿Cuál es el sizeof(MyGizmo) ?

Asumiendo mis implementaciones propuestas arriba, bajo MSVC10 va a ser sizeof(char*) , pero bajo SP1 será sizeof(vector<char>) . Si escribe una aplicación en VC10 SP1 que usa la DLL, el tamaño del objeto se verá diferente de lo que realmente es. La interfaz binaria está modificada.

Para otro tratamiento de esto, consulte C ++ Coding Standards ( link Amazon) número 63.

1 : " A menudo no se puede ". De hecho, puede exportar los componentes de la Biblioteca estándar o cualquier otro componente de la biblioteca de códigos (como Boost) con una buena cantidad de fiabilidad cuando tiene el control completo sobre los toolchains y las bibliotecas.

El problema fundamental es que con las bibliotecas de códigos fuente, los tamaños y las definiciones de las cosas pueden ser diferentes entre diferentes compiladores y diferentes versiones de la biblioteca. Si trabaja en un entorno donde controla estas dos cosas en cualquier lugar donde se use su código, entonces probablemente no tendrá ningún problema. Por ejemplo, en una empresa comercial en la que todos los sistemas se escriben internamente y se usan solo en la empresa, podría ser posible hacerlo.