Pregunta

Interfaces binarias STL

Tengo curiosidad por saber si alguien está trabajando en capas de interfaz compatibles para objetos STL en múltiples compiladores y plataformas para C ++.

El objetivo sería admitir los tipos de STL como tipos de datos de primera clase o intrínsecos.

¿Hay alguna limitación de diseño inherente impuesta por la plantilla en general que evite esto? Esto parece una gran limitación del uso del STL para la distribución binaria.

Teoría: quizás la respuesta es pragmática

  1. Microsoft ha puesto el esfuerzo en .NET y realmente no le importa que el soporte de C ++ STL sea "primera clase".

  2. La fuente abierta no quiere promover la distribución binaria y se centra en hacer las cosas bien con un solo compilador en lugar de un desajuste de 10 versiones diferentes.

Esto parece estar respaldado por mi experiencia con QT y otras bibliotecas: generalmente proporcionan una construcción para el entorno que va a usar. Qt 4.6 y VS2008 Por ejemplo.

Referencias:

¿Fue útil?

Solución

Creo que el problema precedidos Su teoría: C ++ no especifica el ABI (interfaz binaria de aplicación).

De hecho, incluso C no lo hace, pero ser una biblioteca C solo una colección de funciones (y puede ser variables globales) El ABI es solo el nombre de las funciones en sí. Dependiendo de la plataforma, los nombres se pueden destrozar de alguna manera, pero, dado que cada compilador debe ser capaz de colocar calss del sistema, todo termina utilizando la misma convención del constructor de sistemas operativos (en Windows, _cdecl Solo resulta en la preparación de un _ al nombre de la función.

Pero C ++ tiene una sobrecarga, por lo tanto, se requiere un esquema de gestión más complejo. En cuanto a hoy, no existe un acuerdo entre los fabricantes de compiladores sobre cómo se debe hacer tal desglose. Técnicamente es imposible compilar una biblioteca estática C ++ y vincularla a un OBJ C ++ que proviene de otro compilador. Lo mismo es para DLLS.

Y dado que los compiladores son todos diferentes incluso para las funciones de miembros sobrecargados compilados, nadie realmente está proporcionando el problema de las plantillas.

Técnicamente se puede proporcionar introduciendo una redirección para cada tipo paramétrico e introducir tablas de despacho, pero ... esto hace que la función plantada no sea diferente (en términos de envío de llamadas) que las funciones virtuales de las bases virtuales, lo que hace que el rendimiento de la plantilla se vuelva similar al envío de OOP clásico (aunque puede limitar la hinchazón del código ... la compensación no siempre es obvia)

En este momento, parece que no hay interés entre los fabricantes de compiladores de aceptar un estándar común, ya que sacrificará todas las diferencias de rendimiento que cada fabricante puede tener con su propia optimización.

Otros consejos

Las plantillas de C ++ son código generado por tiempo de compilación.
Esto significa que si desea usar una clase plantada, debe incluir su encabezado (declaración) para que el compilador pueda generar el código correcto para la clase plantada que necesita.

Por lo tanto, las plantillas no se pueden competir en archivos binarios.

Lo que otras bibliotecas le brindan son las clases de utilidad base precompilada que no están plantadas.

Los genéricos C#, por ejemplo, se compilan en el código IL en forma de DLLS o ejecutables.
Pero el código IL es como otro lenguaje de programación, por lo que esto permite al compilador leer información de genéricos de la biblioteca incluida.

El código .NET IL se compila en el código binario real en tiempo de ejecución, por lo que el compilador en tiempo de ejecución tiene todas las definiciones que necesita en IL para generar el código correcto para los genéricos.

Tengo curiosidad por saber si alguien está trabajando en capas de interfaz compatibles para objetos STL en múltiples compiladores y plataformas para C ++.

Sí, lo soy. Estoy trabajando en una capa de interfaces estandarizadas que puede (entre otras cosas) usar para pasar referencias "administradas" binarias a instancias de STL, Boost u otros tipos de C ++ a través de los límites de los componentes. La biblioteca (llamada 'Vex') proporcionará implementaciones de estas interfaces, además de fábricas adecuadas para envolver y desenvolver los tipos populares de std :: o Boost ::. Además, la biblioteca proporciona operadores de consultas tipo LINQ para filtrar y manipular el contenido de lo que yo llamo Range y RangeSource. La biblioteca aún no está lista para "volverse pública", pero tengo la intención de publicar una versión temprana de "vista previa" lo antes posible ...

Ejemplo:

com1 pasa una referencia a std::vector<uint32_t> a com2:

com1:

class Com2 : public ICom1 {
    std::vector<int> mVector;

    virtual void Com2::SendDataTo(ICom1* pI)
    {
        pI->ReceiveData(Vex::Query::From(mVector) | Vex::Query::ToInterface());
    }
};

com2:

class Com2 : public ICom2 {
    virtual void Com2::ReceiveData(Vex::Ranges::IRandomAccessRange<uint32_t>* pItf)
    {
        std::deque<uint32_t> tTmp;
        // filter even numbers, reverse order and process data with STL or Boost algorithms
        Vex::Query::From(pItf)
            | Vex::Query::Where([](uint32_t _) -> { return _ % 2 == 0; })
            | Vex::Query::Reverse
            | Vex::ToStlSequence(std::back_inserter(tTmp));
        // use tTmp...
    }
};

Reconocerá la relación con varios conceptos familiares: Linq, Boost.Range, Any_iterator y D's rangos ... Una de las intenciones básicas de 'Vex' no es reinventar la rueda, solo agrega esa capa de interfaz más algunas infraestructuras requeridas y sintácticos azúcar para consultas.

Salud,

Pablo

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top