2009-03-30 15 views
7

Me tocó este problema hace dos años cuando implementé por primera vez nuestras fijaciones SWIG. Tan pronto como expusimos una gran cantidad de código, llegamos al punto en que SWIG generaría archivos C++ tan grandes que el compilador no podría manejarlos. La única forma de evitar el problema era dividir las interfaces en múltiples módulos y compilarlos por separado.¿Es posible dividir un módulo SWIG para compilación, pero volver a unirlo cuando se vincula?

Esto tiene varias desventajas:

• Cada módulo debe saber acerca de las dependencias en otros módulos. Tengo un script para generar los archivos de interfaz que maneja este lado de las cosas, pero agrega complejidad adicional.

• Cada módulo adicional aumenta el tiempo que el enlazador dinámico necesita para cargar el código. He agregado un archivo init .py que importa todos los submódulos, por lo que el hecho de que el código esté dividido es transparente para el usuario, pero lo que siempre está visible son los tiempos de carga larga.

Actualmente estoy revisando nuestros scripts de compilación/proceso de compilación y quería ver si podía encontrar una solución a este problema que fuera mejor que la que tengo ahora. Idealmente, tendría una biblioteca compartida que contiene todo el código del contenedor.

¿Alguien sabe cómo puedo lograr esto con SWIG? He visto un código personalizado escrito en Ruby para un proyecto específico, donde la salida se procesa posteriormente para que esto sea posible, pero cuando analicé la viabilidad de los contenedores de Python, no parece tan fácil.

Respuesta

0

Si se divide correctamente, los módulos no necesitan necesariamente tener las mismas dependencias que los demás, solo lo que es necesario para hacer la compilación. Si divide las cosas adecuadamente, puede tener bibliotecas sin dependencias cíclicas. El problema con el uso de múltiples bibliotecas es que, de manera predeterminada, SWIG declara su código de tiempo de ejecución estáticamente y, como resultado, como problemas al pasar objetos de un módulo a otro. Debe habilitar una versión compartida del código de tiempo de ejecución de SWIG.

De la documentación (TRAGO enlace de documentación página Web se rompe):

Las funciones de tiempo de ejecución son privados para cada módulo generada TRAGO. Es decir, las funciones de tiempo de ejecución se declaran con enlace "estático" y son visibles solo para las funciones de contenedor definidas en ese módulo. El único problema con este enfoque es que cuando se utiliza más de un módulo SWIG en la misma aplicación , esos módulos a menudo necesitan para compartir información de tipo. Esto es especialmente cierto para los programas C++ donde SWIG debe recopilar y compartir información sobre herencia relaciones que cruzan los límites del módulo .

Comprobar que el artículo en la documentación descargada (sección 16.2 El código TRAGO tiempo de ejecución), y se te dará más detalles sobre cómo activar esta forma que los objetos pueden ser manejados adecuadamente cuando se pasa de un módulo a otro .

FWIW, no he trabajado con Python SWIG, pero he hecho Tcl SWIG.

+0

Creo que se ha perdido un poco el punto: no tengo problemas para pasar cosas de un módulo a otro, eso funciona bien, importa la declaración de "importación". El problema es que quiero vincular varios módulos en una biblioteca compartida para acelerar los tiempos de carga al importar el código. – jkp

+0

Ah, perdón por eso, no hay solución para acelerarlo. Con Tcl, pudimos retrasar la carga de los módulos hasta que se necesitaron utilizando el mecanismo del paquete. Esto ayudó a acelerar las cosas, pero en cuanto a simplemente acelerar la carga, no hay dados. –

0

Acabo de hacer un hack equivalente para la biblioteca TCL: utilizo varios módulos SWIG, generando varios archivos .cpp que se compilan en varios archivos .o pero los compilo todos en una sola.por lo que el archivo que se carga con un solo comando TCL "carga".

La idea es que crea un módulo trago superior (Top) que llama a las funciones de inicialización de todos los submódulos (SUB1 y Sub2):

%module Top 
%header %{ 
    extern "C" { 
    SWIGEXPORT int Sub1_Init(Tcl_Interp *); 
    SWIGEXPORT int Sub2_Init(Tcl_Interp *); 
} 
%init %{ 
    if (Sub1_Init(interp) != TCL_OK) {return TCL_ERROR;} 
    if (Sub2_Init(interp) != TCL_OK) {return TCL_ERROR;} 
%} 

No hay nada especial en los archivos de submódulos. Termino con el archivo Top.so que cargo desde TCL con el comando "cargar ./Top.so"

No conozco Python pero es probable que sea similar. Sin embargo, es posible que deba comprender cómo se cargan las extensiones de Python.

Cuestiones relacionadas