2013-08-01 11 views
7

Ho un numero di funzioni template C++ dichiarate e implementate in un file di intestazione C++ e voglio accedere ad alcune delle funzioni in Cython.Chiamare le funzioni template C++ esterne in Cython

Supponiamo che il codice C++ è in header.hpp come segue

template <class T> 
T doublit(T& x) { 
    return 2*x; 
} 

cosa ho bisogno di scrivere nel file .pyx e nel file setup.py in modo che possa utilizzare la funzione in Python come

>>> import modname 
>>> print modname.doublit(3) 
6 

PS: è possibile accedere alle stesse funzioni all'interno di PYPY? E se sì, come?


Grazie per l'aiuto. Ma ho ulteriori difficoltà (sotto) mentre cerco di seguire la tua strada.

doublit.h

template <class T> 
T doublit(T& x) { 
    return 2*x; 
} 

cdoublit.pxd

cdef extern from "doublit.h": 
    cdef int doublit1 "doublit<int>"(int& foo) 
    cdef double doublit2 "doublit<double>"(double& foo) 

doublit.pyx

# main.pyx file 
from cdoublit cimport * 

cdef int n1 = 5 
cdef double n2 = 5.0 
print(doublit1(n1)) 
print(doublit2(n2)) 

e setup.py

from distutils.core import setup 
from distutils.extension import Extension 
from Cython.Distutils import build_ext 

ext_modules = [Extension("doublit", ["doublit.pyx"])] 

setup(
name = 'Learning Cython', 
cmdclass = {'build_ext': build_ext}, 
ext_modules = ext_modules 
) 

Infine, ho costruito come

>>> python setup.py build_ext --inplace 

ma ottengo la seguente eccezione:

###:doublit markma$ python setup.py build_ext --inplace 
running build_ext 
cythoning doublit.pyx to doublit.c 
building 'doublit' extension 
creating build 
creating build/temp.macosx-10.6-intel-2.7 
gcc-4.2 -fno-strict-aliasing -fno-common -dynamic -isysroot /Developer/SDKs/MacOSX10.6.sdk -arch i386 -arch x86_64 -g -O2 -DNDEBUG -g -O3 -I/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c doublit.c -o build/temp.macosx-10.6-intel-2.7/doublit.o 
In file included from doublit.c:311: 
doublit.h:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘<’ token 
doublit.c: In function ‘initdoublit’: 
doublit.c:782: error: ‘doublit’ undeclared (first use in this function) 
doublit.c:782: error: (Each undeclared identifier is reported only once 
doublit.c:782: error: for each function it appears in.) 
doublit.c:782: error: expected expression before ‘int’ 
doublit.c:793: error: expected expression before ‘double’ 
In file included from doublit.c:311: 
doublit.h:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘<’ token 
doublit.c: In function ‘initdoublit’: 
doublit.c:782: error: ‘doublit’ undeclared (first use in this function) 
doublit.c:782: error: (Each undeclared identifier is reported only once 
doublit.c:782: error: for each function it appears in.) 
doublit.c:782: error: expected expression before ‘int’ 
doublit.c:793: error: expected expression before ‘double’ 
lipo: can't figure out the architecture type of: /var/folders/ip/ip5rkteZFbWPEtzhmxRdVE+++Tc/-Tmp-//ccvaEGqZ.out 
error: command 'gcc-4.2' failed with exit status 1 
+1

Immagino che sia necessario creare un'istanza delle funzioni del modello. –

+0

Immagino sia necessario specificare C++ come linguaggio da utilizzare in caso di traduzione da cython. – jepio

risposta

4

Cython supporta la sintassi del modello, ma solo per le classi (come di Cython 0.19.1).

Anche se si può avvolgere funzioni template utilizzando la seguente sintassi:

# doublit.pxd file 
cdef extern from "doublit.h": 
    cdef int doublit1 "doublit<int>"(int& foo) 
    cdef double doublit2 "doublit<double>"(double& foo) 

# main.pyx file 
from doublit cimport * 
cdef int n1 = 5 
cdef double n2 = 5.0 
print(doublit1(n1)) 
print(doublit2(n2)) 

Si perde l'automazione, ma almeno si può farlo funzionare.

UPDATE

Cython 0.20 aggiunge il supporto per le chiamate alle funzioni di template C++. Cython 0.20 beta release announced.

+0

Grazie per l'aiuto. Ma ho avuto ulteriori difficoltà mentre cerco di seguire la tua strada. –

+0

Puoi tornare al mio post e dare un'occhiata? Thx –

+0

@YunzhiMa Ho già risposto alla tua risposta, vedi il mio commento sotto la tua risposta. –

Problemi correlati