2013-08-01 41 views
7

Tôi có một số hàm mẫu C++ được khai báo và triển khai trong tệp tiêu đề C++ và tôi muốn truy cập một số hàm trong Cython.Gọi hàm C++ mẫu bên ngoài trong Cython

Giả sử C++ code đang trong header.hpp như sau

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

gì tôi cần phải viết trong file .pyx và trong file setup.py để tôi có thể sử dụng chức năng bằng Python như

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

PS: Có thể truy cập các chức năng giống nhau trong PYPY không? Và, nếu có, làm thế nào?


Cảm ơn bạn đã trợ giúp. Nhưng tôi có nhiều khó khăn hơn (dưới đây) khi tôi cố gắng theo cách của bạn.

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

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

Cuối cùng, tôi xây dựng như

>>> python setup.py build_ext --inplace 

nhưng tôi nhận được ngoại lệ sau đây:

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

Tôi sẽ hình dung bạn cần khởi tạo các chức năng mẫu. –

+0

Tôi sẽ tưởng tượng bạn cần chỉ định C++ làm ngôn ngữ cho cython để sử dụng khi dịch. – jepio

Trả lời

4

Cython hỗ trợ mẫu cú pháp nhưng chỉ cho các lớp học (tính Cython 0.19.1).

Mặc dù bạn có thể quấn chức năng mẫu bằng cách sử dụng cú pháp sau:

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

Bạn mất tự động hóa, nhưng ít nhất bạn có thể làm cho nó hoạt động.

CẬP NHẬT

Cython 0,20 thêm hỗ trợ cho gọi C++ chức năng template. Cython 0.20 beta release announced.

+0

Cảm ơn bạn đã trợ giúp. Nhưng tôi đã gặp nhiều khó khăn hơn khi tôi cố gắng đi theo con đường của bạn. –

+0

Bạn có thể quay lại bài đăng của tôi và xem không? Thx –

+0

@YunzhiMa Tôi đã trả lời câu trả lời của bạn, xem bình luận của tôi bên dưới câu trả lời của bạn. –