Calling C ++ Template External Functions in Cython

I have a number of C ++ template functions declared and implemented in the C ++ header file, and I want to access some functions in Cython.

Assume C ++ code is in header.hpp as follows

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

What do I need to write in the .pyx file and in the setup.py file so that I can use this function in Python as

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

PS: Is it possible to access the same functions in PYPY? And if so, how?


Thanks for the help. But I have additional difficulties (below), as I try to follow your path.

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)) 

and 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 ) 

Finally, I create as

 >>> python setup.py build_ext --inplace 

but I get the following exception:

 ###: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 
+7
python cython
source share
1 answer

Cython supports template syntax, but only for classes (as from Cython 0.19.1).

Although you can wrap template functions using the following syntax:

 # 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)) 

You lose automation, but at least you can make it work.

UPDATE

Cython 0.20 adds support for calling C ++ template functions. beta version of Cython 0.20 announced .

+4
source share

All Articles