una hacer como aplicacion c++ virtual binary-compatibility

hacer - Cómo diseñar una API de C++ para la extensibilidad binaria compatible



como hacer una aplicacion en c++ (5)

Estoy diseñando una API para una biblioteca C ++ que se distribuirá en un dll / objeto compartido. La biblioteca contiene clases polimórficas con funciones virtuales. Me preocupa que si expongo estas funciones virtuales en la DLL API, me recorte de la posibilidad de extender las mismas clases con más funciones virtuales sin romper la compatibilidad binaria con las aplicaciones creadas para la versión anterior de la biblioteca.

Una opción sería utilizar el lenguaje PImpl para ocultar todas las clases que tienen funciones virtuales, pero que también parecen tener sus limitaciones: de esta manera las aplicaciones pierden la posibilidad de subclasificar las clases de la biblioteca y anular los métodos virtuales.

¿Cómo diseñaría una clase API que se puede subclasificar en una aplicación, sin perder la posibilidad de ampliar la API con métodos virtuales (no abstractos) en una nueva versión de la DLL mientras se mantiene compatible con versiones anteriores binarias?

Actualización: las plataformas de destino para la biblioteca son windows / msvc y linux / gcc.


Creo que malinterpretas el problema de las subclases.

Aquí está tu Pimpl:

// .h class Derived { public: virtual void test1(); virtual void test2(); private; Impl* m_impl; }; // .cpp struct Impl: public Base { virtual void test1(); // override Base::test1() virtual void test2(); // override Base::test2() // data members }; void Derived::test1() { m_impl->test1(); } void Derived::test2() { m_impl->test2(); }

Ver ? No hay problema con anular los métodos virtuales de Base , solo necesita asegurarse de volver a declararlos virtual en Derived para que aquellos derivados de Derived sepan que también pueden reescribirlos (solo si así lo desea, que por cierto es una excelente forma de proporcionando una final para aquellos que carecen de ella), y aún puede redefinirlo para usted en Impl que incluso puede llamar a la versión Base .

No hay problema con Pimpl allí.

Por otro lado, pierdes polimorfismo, lo que puede ser problemático. Depende de usted decidir si quiere polimorfismo o solo composición.


Hace varios meses escribí un artículo titulado "Compatibilidad binaria de bibliotecas compartidas implementadas en C ++ en sistemas GNU / Linux" [ pdf ]. Si bien los conceptos son similares en el sistema de Windows, estoy seguro de que no son exactamente lo mismo. Pero después de leer el artículo, puede obtener una noción de lo que está sucediendo en el nivel binario de C ++ que tiene algo que ver con la compatibilidad.

Por cierto, la interfaz binaria de la aplicación GCC se resume en un borrador de documento estándar " Itanium ABI ", por lo que tendrá una base formal para un estándar de codificación que elija.

Solo para un ejemplo rápido: en GCC puede extender una clase con más funciones virtuales, si ninguna otra clase lo hereda. Lee el artículo para un mejor conjunto de reglas.

Pero de todos modos, las reglas a veces son demasiado complejas para comprenderlas. Por lo tanto, podría interesarle una herramienta que verifique la compatibilidad de dos versiones determinadas: abi-compliance-checker para Linux.



La compatibilidad binaria de C ++ es generalmente difícil, incluso sin herencia. Mira a GCC por ejemplo. En los últimos 10 años, no estoy seguro de cuántos cambios ABI han tenido. Entonces MSVC tiene un conjunto diferente de convenciones, por lo que no se puede vincular a eso con GCC y viceversa ... Si lo comparas con el mundo C, el compilador interoperativo parece un poco mejor allí.

Si estás en Windows deberías mirar COM. A medida que introduce nuevas funciones, puede agregar interfaces. Luego las personas que llaman pueden QueryInterface() para que el nuevo exponga esa nueva funcionalidad, e incluso si termina cambiando mucho las cosas, puede dejar la implementación anterior allí o escribir calces para las interfaces anteriores.


Si expone la clase PImpl en un archivo de encabezado, puede heredar de ella. Todavía puede mantener la portabilidad hacia atrás ya que las clases externas contienen un puntero al objeto PImpl. Por supuesto, si el código de cliente de la biblioteca no es muy inteligente, podría hacer un mal uso de este objeto PImpl expuesto y arruinar la compatibilidad binaria con versiones anteriores. Puede agregar algunas notas para advertir al usuario en el archivo de encabezado de PImpl.