una programacion librerías librerias libreria lenguaje generacion entre dinámicas dinamicas diferencia desarrolladas crea con compilar como clases biblioteca c linux memory-management shared-libraries binary-compatibility

programacion - librerias dinamicas c



Buenas prácticas para escribir bibliotecas dinámicas de C[DSO](compatibilidad binaria+gestión de memoria) (4)

¿Hay alguna herramienta para verificar la compatibilidad binaria?

ABI Compliance Checker : una herramienta para verificar la compatibilidad binaria con versiones anteriores de una biblioteca C / C ++ compartida (DSO).

¿Hay algún otro documento que pueda leer?

Vea esta larga lista de artículos sobre compatibilidad binaria de bibliotecas compartidas.

¿Cómo diseñar interfaces que siguen siendo compatibles con versiones anteriores?

El uso de campos reservados / rellenos es un método general para preservar la compatibilidad de las bibliotecas C. Pero también hay muchos otros.

Además, ¿hay alguna manera de agregar nuevos métodos / funciones a una biblioteca sin romper realmente la compatibilidad binaria? Asumo que agregar estas cosas cambiaría el tamaño y el diseño de la biblioteca, lo que rompería la compatibilidad.

Las funciones C añadidas no rompen la compatibilidad binaria hacia atrás de DSO en Linux y Mac. Lo mismo es cierto en Windows y Symbian, pero debe agregar nuevas funciones solo al final de un archivo .DEF. Sin embargo, la compatibilidad hacia adelante siempre se rompe con funciones adicionales.

Los métodos añadidos de C ++ rompen la compatibilidad binaria solo si son virtuales o puramente virtuales , porque el diseño de v-table puede cambiar. Pero su pregunta parece ser sobre bibliotecas de C solamente.

Tengo cierta experiencia en la escritura de bibliotecas C, pero nunca he leído ningún documento formal que describa las buenas prácticas al escribir esas bibliotecas. Mi pregunta se refiere principalmente a 2 temas:

  1. ¿Cómo mantener la compatibilidad binaria? (He oído hablar de la expresión pImpl, d-pointer)
  2. ¿Cómo diseñar interfaces que siguen siendo compatibles con versiones anteriores?

Lo principal acerca de la compatibilidad binaria que puedo ver en mi investigación es que puedo hacer que las bibliotecas sean compatibles con binarios mediante el uso de la expresión pImpl, pero cambiar la estructura / agregar nuevos miembros de datos, etc. puede afectar su compatibilidad binaria incluso al utilizar pImpl. Además, ¿hay alguna manera de agregar nuevos métodos / funciones a una biblioteca sin romper realmente la compatibilidad binaria? Asumo que agregar estas cosas cambiaría el tamaño y el diseño de la biblioteca, lo que rompería la compatibilidad.

¿Hay alguna herramienta para verificar la compatibilidad binaria?

Ya leí estos artículos. ¿Hay algún otro documento que pueda leer?

http://en.wikipedia.org/wiki/Opaque_pointer

http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++

Además, hay artículos que describen problemas de propiedad de la memoria en el contexto del diseño de interfaces de biblioteca. ¿Cuáles son las convenciones generales? ¿A quién pertenece la memoria, por cuánto tiempo, quién es el responsable de desasignar la memoria, etc.?



Los principales problemas de compatibilidad son:

  • firmas de funciones
  • formato de los datos a los que acceden tanto la biblioteca como la persona que llama
  • variables globales en la biblioteca a la que accede la persona que llama
  • código de biblioteca que termina en la persona que llama debido a macros / funciones en línea en los encabezados
  • #define / enum valores constantes en encabezados compartidos

Entonces, la mejor lista de pautas que puedo dar es:

  • Nunca cambie la firma (tipos de retorno / argumento) de ninguna interfaz pública. Si necesita expandir una interfaz, en su lugar, agregue una nueva función que requiera más argumentos (piense dup frente a dup2 o wait frente a waitpid ).
  • En la medida de lo posible, use punteros a objetos de datos opacos totalmente encapsulados y ni siquiera exponga la definición de tales estructuras en los encabezados públicos ( struct tipos de struct incompletos).
  • Cuando quiera compartir una estructura, disponga que la persona que llama nunca declare las variables de ese tipo de estructura y, en su lugar, llame a funciones explícitas de asignación / libre en la biblioteca. Nunca cambie el tipo de miembros existentes o elimine miembros existentes; en su lugar, agregue nuevos miembros solo al final de la estructura.
  • No exponga las variables globales de las bibliotecas, punto. A menos que comprenda "traslados de copias", es mejor no preguntar por qué. Simplemente no lo hagas.
  • No coloque funciones en línea o macros que contengan código en los encabezados públicos de su biblioteca a menos que use la interfaz expuesta documentada que se mantendrá permanente. Si pinchan en el interior de objetos de datos opacos, causarán problemas cuando decida cambiar las partes internas.
  • No renumere las constantes #define / enum existentes. Solo agregue nuevas constantes con valores previamente no utilizados.

Si sigues estas pautas, creo que estás cubierto al menos en un 95%.


Un par de cosas para agregar a lo que R. dijo:

Dado que parece que estás hablando de C ABI y no de C ++ ABI:

cambiar la estructura / agregar nuevos miembros de datos, etc. puede afectar su compatibilidad binaria, incluso al usar pImpl

Ese no debería ser el caso cuando se usa pIMpl - si los usuarios externos del objeto solo tienen un puntero / manejador opaco para el objeto y solo la biblioteca trata con las partes internas de la estructura, entonces, por definición, lo que trata con las partes internas de la estructura es compatible con ella.

¿Hay alguna forma de agregar nuevos métodos / funciones a una biblioteca sin romper realmente la compatibilidad binaria? Asumo que agregar estas cosas cambiaría el tamaño y el diseño de la biblioteca, lo que rompería la compatibilidad.

Agregar nuevas funciones o cambiar el tamaño o el diseño de la biblioteca compartida no rompe la compatibilidad binaria. Como la vinculación a la dirección de la función no se realiza hasta que la biblioteca compartida se carga en el proceso, un cambio en la ubicación de la función objetivo no es un problema.