2012-01-31 16 views
8

Leí los siguientes dos hilos en wrapping C library y C++ library, no estoy seguro de que lo obtenga todavía. La biblioteca C++ con la que estoy trabajando usa clase y plantilla, pero no de manera demasiado sofisticada. ¿Cuáles son los problemas o advertencias de envolverlo con ctypes (además del punto de que puede hacerlo en python puro, etc.)?¿Está mal envolviendo la biblioteca de C++ con ctypes?

PyCXX, Cython y boost :: python son otras tres opciones que las personas mencionaron, ¿hay algún consenso sobre cuál es más adecuado para C++?

Gracias

Oliver

Respuesta

9

para C++ una biblioteca que sean accesibles desde Python debe utilizar nombres de exportación C, lo que básicamente significa que una función llamada foo será accesible desde ctypes como foo.

Esto se puede lograr solamente encerrando la interfaz pública con export C {}, que a su vez no permite la sobrecarga de funciones y plantillas en el mismo (sólo la interfaz pública de la biblioteca para ser envuelto es relevante, el funcionamiento interno no son y pueden utilizar cualquier característica de C++ que les guste).

Motivo para esto es que los compiladores C++ usan un mecanismo llamado name mangling para generar nombres únicos para símbolos sobrecargados o con plantillas. Mientras que ctypes aún encontraría una función siempre que supiera su nombre destrozado, el esquema de manipulación dependerá del compilador/enlazador que se utilice y no es nada en lo que pueda confiar. En resumen: no use los tipos para envolver las bibliotecas que usan funciones de C++ en su interfaz pública.

Cython tiene un enfoque diferente. Le ayuda a construir un módulo de extensión C que hace la interfaz con la biblioteca original. Por lo tanto, el enlace a la biblioteca de C++ se realiza mediante el mecanismo de vinculación de C++ regular, evitando así el problema mencionado anteriormente. El problema con Cython es que las librerías de extensión C necesitan ser recompiladas para cada plataforma, pero de todos modos, esto también se aplica a la biblioteca C++.

Personalmente, yo diría que, en la mayoría de los casos, el momento de encender Cython es un tiempo bien empleado que finalmente rendirá en comparación con ctypes (con la excepción de interfaces Cish realmente simples).

No tengo ninguna experiencia con boost.python, así que no puedo comentar sobre ella (sin embargo, no tengo la impresión de que sea muy popular tampoco).

+0

¡Gracias por mencionar a Cython como una opción! Lo elegí para envolver C api y tuve una experiencia positiva: es como escribir Python con algunas líneas de C en él, y le da mucho control. Una cosa que me costó mucho fue hacer que el proceso de compilación funcionara correctamente: terminé compilando previamente los archivos de Cython antes de crear la distribución de fuente. Si alguien tiene problemas similares, expliqué en detalle cómo envolví mi C api con Cython aquí, incluido el proceso de compilación: http://martinsosic.com/development/2016/02/08/wrapping-c-library-as-python -module.html – Martinsos

14

En defensa de boost::python, dada la respuesta de Alexander en ctypes:

pitón Boost proporciona una interfaz muy "C++" entre el código C++ y Python - incluso hacer las cosas como las subclases pitón permitidos de clases de C++ para anular los métodos virtuales es relativamente sencillo. Aquí hay una lista de potentes características:

  • Permitir que las subclases de python anulen los métodos virtuales de clases en C++.
  • puente entre std::vector<>, std::map<> casos y listas de Python y los diccionarios electrónicos (utilizando vector_indexing_suite y map_indexing_suite)
  • el intercambio automático de recuento de referencia en punteros inteligentes (boost::shared_ptr, etc) con recuentos de referencia de Python (y se puede extender esto a cualquier puntero inteligente)
  • Control de propiedad detallado al pasar argumentos y devolver valores de funciones.

Básicamente, si tiene un diseño en el que desea exponer una interfaz C++ de una manera fiel al idioma, entonces boost :: python es probablemente la mejor manera de hacerlo.

Las únicas desventajas son el aumento del tiempo de compilación (boost :: python hace un uso extenso de las plantillas) y, a veces, mensajes de error opacos si no se hacen las cosas bien.

+2

El otro problema es el fuerte acoplamiento de las versiones de boost y python. Por ejemplo, si actualiza su versión de python, tendrá que reconstruir la versión de boost – user1827356

Cuestiones relacionadas