2010-01-30 9 views
5

Tengo la necesidad de envolver una biblioteca C++ existente para su uso en Python. Después de leer this answer on choosing an appropriate method to wrap C++ for use in Python, decidí ir con Py ++.Uso del código generado por Py ++ como una extensión de Python

Caminé por el tutorial for Py++, usando los archivos del tutorial, y obtuve el resultado esperado en generated.cpp, pero no he resuelto qué hacer para usar realmente el código generado como una extensión que puedo importar en Python . Estoy seguro de que tengo que compilar el código, pero ¿con qué? ¿Se supone que debo usar bjam?

+0

Ha visto este anuncio del autor de Py ++? http://mail.python.org/pipermail/cplusplus-sig/2009-January/014198.html – torial

+0

Lo tengo, pero aún termina antes de responder a mi pregunta: "El último paso: se genera el código". Creo que el último paso debería dejar al usuario con código compilado e importable, no solo generado. – gotgenes

Respuesta

6

Py ++ genera la sintaxis que utiliza junto con boost :: python para generar puntos de entrada de python en su aplicación. Asumiendo que todo va bien con Py ++, necesita descargar el framework de Boost, y agregar el directorio boost y el boost :: python lib a su proyecto y luego compilar con el cpp generado por Py ++.

Puede usar cualquier sistema de compilación que desee para su proyecto, pero boost está diseñado con bjam. Debe elegir si desea una lib estática o un impulso dinámico python lib luego siga las instrucciones para generar boost here.

Si está en Windows, debe cambiar la extensión de su biblioteca creada de .dll a.pyd. Y sí, tiene que ser un proyecto de biblioteca, esto no funciona con ejecutables.

Luego, coloque el pyd donde el python en su máquina puede encontrarlo y entre en python y ejecute import [Your-library-name] y esperemos que todo funcione.

Una nota final, el nombre dado en generated.cpp en esta macro:

BOOST_PYTHON_MODULE(-name-) 

tiene que ser el nombre exacto de su proyecto, de lo contrario pitón se quejará.

Acabo de pasar por todo esto hace menos de un mes, así que sé sobre la confusión.

Una cosa que hice para hacer que mi extensión de python fuera muy fácil de usar mientras construía la biblioteca y las pruebas, era construir boost :: python y python en mi entorno de compilación. De esta forma, el pyd termina exactamente donde yo lo quiero y los usuarios no necesitan instalar Python para ejecutarlo con mi extensión. Sin embargo, eso puede ser excesivo para lo que estás haciendo.

Edit: Si desea que su extensión se instale y compile fácilmente en una máquina, consulte python's setuptools. Con solo unas simples líneas, puede tener python compilar e instalar su paquete por usted. Un inconveniente, sin embargo, es que no es compatible con IDE para aquellos de nosotros que nos gusta desarrollar en Visual Studio.

3

La siguiente respuesta me fue proporcionada por Roman Yakovenko on the Python C++-sig mailing list; Lo estoy publicando aquí, con ediciones menores, para el beneficio de la comunidad Stack Overflow.

Todavía no entiendo completamente la respuesta, pero sentí que me apunta en la dirección correcta.


Después de generar el código, debe compilarlo. Para este propósito, puede usar su sistema de compilación favorito. Yo uso bjam solo para compilar boost. Después de esto, prefiero usar scons (en Windows y en Linux).

El siguiente es un ejemplo de archivo de sconstruct, que se utiliza para compilar una de las unittests Py ++ (esto se genera el código también :-)):

import sys 
env = Environment() 

if 'linux' not in sys.platform: 
    env['MSVS'] = {'VERSION': ''} 
    env['MSVS_VERSION'] = '' 
    Tool('msvc')(env) 

t = env.SharedLibrary(
    target=r'abstract_classes', 
    source=[r'/home/roman/language-binding/sources/pyplusplus_dev/unittests/temp/abstract_classes.cpp'], 
    LIBS=[r"boost_python"], 
    LIBPATH=[r"", r"/home/roman/include/libs"], 
    CPPPATH=[ 
     r"/home/roman/boost_svn", 
     r"/usr/include/python2.6", 
     r"/home/roman/language-binding/sources/pyplusplus_dev/unittests/temp", 
     r"/home/roman/language-binding/sources/pyplusplus_dev/unittests/data", 
     r"/home/roman/boost_svn" 
    ], 
    CCFLAGS=[ ], 
    SHLIBPREFIX='', 
    SHLIBSUFFIX='.so' 
) 

Debido a que su generador de código escrito en Python, puede continuar donde Py ++ se detiene y genera su archivo "make" favorito. Puedes ir incluso padre. Las pruebas Py ++ generan el código, compilan, cargan el nuevo módulo y prueban la funcionalidad. Todo esto se hace en un solo proceso independiente.

1

escribí un pequeño makefile con lo siguiente:

GNUmakefile:

PYTHON_INC=$(shell python-config --includes) 
PYTHON_LIBS=$(shell python-config --libs) 
BOOST_LIBS=-lboost_python 

all: 
    g++ -W -Wall $(PYTHON_INC) $(PYTHON_LIBS) $(BOOST_LIBS) -fPIC -shared generated.cpp -o hw.so 

y luego cargar el .so creados en ipython para jugar un rato con él:

In [1]: import hw 
In [2]: a = hw.animal('zebra') 
In [3]: a.name() 
Out[3]: 'zebra' 
Cuestiones relacionadas