Pregunta

Durante los meses que he escrito algunas buenas suficiente funcionalidad genérica que quiero construir como una biblioteca de enlace y dinámicamente contra en lugar de importar archivos de 50 y pico de cabecera / fuente.

El proyecto se mantiene en Xcode y Dev-C ++ (entiendo que voy a tener que ir a la línea de comandos para hacer lo que quiero) y tienen que enlazar con OpenGL y SDL (de forma dinámica en el caso de SDL). Plataformas de destino son Windows y OS X.

Lo que estoy viendo en absoluto?

  • ¿Cuál será el punto de entrada de mi biblioteca si necesita uno?
  • ¿Qué tengo que cambiar en mi código? (Convenciones de llamada?)
  • ¿Cómo liberarlo? Mi punto de vista es que los encabezados y el compilado biblioteca (.dll, .dylib (, .framework), lo que va a ser) tiene por qué ser disponible para el proyecto - especialmente como la funcionalidad de la plantilla No se pueden incluir en la biblioteca la naturaleza.
  • ¿Qué más tengo que tener en cuenta?
¿Fue útil?

Solución

Me gustaría recomendar edificio como una biblioteca StatC en lugar de una DLL. Muchos de los problemas de la exportación de C ++ funciones y clases desaparece si lo hace, a condición de que sólo se van a enlazar con el código producido por el mismo compilador que construyó la biblioteca con.

La construcción de una biblioteca estática es muy fácil, ya que es sólo una colección de archivos .o / obj - un poco como un archivo ZIP, pero sin compresión. No hay necesidad de exportar nada - sólo incluye la biblioteca en la lista de archivos que sus enlaces con la aplicación. Para acceder a las funciones o clases específicas, basta con incluir el archivo de cabecera correspondiente. Tenga en cuenta que no puede deshacerse de los archivos de cabecera -. El modelo de compilación ++ C, en particular para las plantillas, depende de ellos

Otros consejos

Puede ser problemático para exportar una biblioteca de clases C ++ de una biblioteca dinámica, pero es posible.
Es necesario marcar cada función para ser exportados de la DLL (sintaxis depende del compilador). Estoy a hurgar para ver si puedo encontrar la manera de hacer esto desde Xcode. En VC es __declspec (dllexport) y en CodeWarrior es #pragma exportación de / #pragma exportación fuera.

Esto es perfectamente razonable si sólo está utilizando su binario en el local. Sin embargo, un problema es que los métodos de C ++ se nombran de manera diferente por diferentes compiladores. Esto significa que nadie que utiliza un compilador diferente será capaz de utilizar el archivo DLL, a menos que sólo está exportando funciones C.

Además, es necesario asegurarse de que el partido de convenciones de llamada en la DLL y el cliente de la DLL. Esto tampoco significa que usted debe tener el mismo por defecto llamando bandera convención pasado al compilador para el archivo DLL o el cliente, o mejor, establezca explícitamente la convención de llamada para cada función exportada en el archivo DLL, por lo que se no importa lo que el defecto es para el cliente.

En este artículo se explica el problema de nomenclatura: http://en.wikipedia.org/wiki/Name_decoration

El estándar de C ++ no define un estándar de ABI, y eso es una mala noticia para las personas que tratan de construir bibliotecas de C ++. Esto significa que se obtiene un comportamiento diferente de su código compilado en función de los cuales se utilizaron banderas para su recopilación, y que puede conducir a errores misteriosos en el código que compila y enlaza muy bien.

Esto se extiende más allá de las diferentes convenciones de llamada - código C ++ puede ser compilado para apoyar o no RTTI, manejo de excepciones, y con varias optimizaciones que pueden afectar la el diseño de memoria de las instancias de clase, que código C ++ se basa en

Así que, ¿qué se puede hacer? Me gustaría construir librerías de C ++ dentro de mi árbol de código fuente, y asegúrese de que están construidas como parte de la construcción de mi proyecto, y que todas las bibliotecas y el código que vincula a ellos utilizar los mismos parámetros del compilador.

Tenga en cuenta que el nombre mangling, que se suponía que le impide al menos desde la vinculación de archivos de objetos que fueron compilados con compiladores diferentes banderas / compilador sólo funciona en su mayoría, y hay ciertas cosas que puede hacer, especialmente con GCC, que dará lugar a código que enlaza muy bien y falla en tiempo de ejecución.

Hay que ser muy cuidadoso con bibliotecas de proveedores suministrada dinámica C ++ (QT en la mayoría de las distribuciones de Linux, por ejemplo.) He visto casos de bibliotecas de proveedores suministrada que fueron compilados en formas que impiden ciertas cosas funcionen correctamente. Por ejemplo, algunos RedHat Linux libera (tal vez todos ellos) excepciones discapacidad en QT, lo que hacía imposible atrapar excepciones en main () si las excepciones fueron arrojados en una devolución de llamada QT. Diversión.

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