我正在研究一個項目,我有一個可用的大型C++代碼庫,我想用cython包裝並在Python中提供。在這種情況下,我正面臨着一些C++函數返回Vector對象或簡單對象(具有多個屬性)的情況。我想將這個對象返回給Python,以便可以訪問它的值。Cython - 將由C++函數返回的C++(向量和非向量)對象公開給Python
做這件事,我幾乎完全以下這篇文章:How to expose a function returning a C++ object to Python without copying the object?
我有一個非常類似的要求。請參閱移動在上述論壇中實施/使用的構造。
以下是我的代碼,我想實現的簡單(非矢量情況下):
test_header.pxd
from libcpp.vector cimport vector
from libcpp.string cimport string
from libcpp.map cimport map
cdef extern from "main_class.h":
cdef cppclass main_class:
int ID1
double ID2
cdef extern from "class2.h":
cdef cppclass class2:
class2() except +
class2(const double& T) except +
void Add(const main_class& ev)
const vector[main_class]& GetEvs()
#Process Class
cdef extern from "Pclass.h":
cdef cppclass Pclass:
Pclass(const unsigned& n, const unsigned& dims) except +
unsigned GetDims()
double processNext(const class2& data, const unsigned& num_iter)
cdef extern from "main_algo.h":
#TODO: Check if inheritance works correctly, virtual functions, objects, std::vector
cdef cppclass main_algo:
main_algo(const unsigned& dims) except +
main_class getNext(Pclass& pr, const class2& d)
test.pyx
from header cimport main_class, class2, Pclass, main_algo
from libcpp.vector cimport vector
from libcpp.string cimport string
from libcpp.map cimport map
cdef extern from "<utility>":
vector[class2]&& move(vector[class2]&&)
main_class&& move(main_class&&)
cdef class main_class_2:
cdef main_class* thisptr
cdef main_class_3 evs
def __cinit__(self,main_class_3 evs):
self.evs = evs
self.thisptr = &evs.evs
cdef class main_class_3:
cdef main_class evs
cdef move_from(self, main_class&& move_this):
self.evs = move(move_this)
cdef class implAlgo:
cdef:
main_algo *_thisptr
def __cinit__(implAlgo self):
self._thisptr = NULL
def __init__(implAlgo self, unsigned dims):
self._thisptr = new main_algo(dims)
def __dealloc__(implAlgo self):
if self._thisptr != NULL:
del self._thisptr
cdef int _check_alive(implAlgo self) except -1:
if self._thisptr == NULL:
raise RuntimeError("Wrapped C++ object is deleted")
else:
return 0
cdef getNext(implAlgo self, Pclass& p, const class2& s):
self._check_alive()
cdef main_class evs = self._thisptr.getNext(p, sq)
retval = main_class_3()
retval.move_from(move(evs))
return retval
在這裏,類別main_algo
實施方法getNext()
返回ns類main_class
的對象。
從test.pyx中,我想將此對象返回到可以訪問其值的純python文件。
當我嘗試編譯上面的代碼時,我在幾處使用該方法的地方得到了多個 實例,並且出現了像')'或'*'這樣的不同令牌的類似錯誤。一些示例錯誤是:
sources.cpp:5121:70: error: expected primary-expression before ‘*’ token
__pyx_vtable_11Cython_test_7sources_main_class_3.move_from = (PyObject *(*)(struct __pyx_obj_11Cython_test_7sources_main_class_3 *, main_class &&))__pyx_f_11Cython_test_7sources_8main_class_3_move_from;
^
sources.cpp:5121:73: error: expected primary-expression before ‘)’ token
__pyx_vtable_11Cython_test_7sources_main_class_3.move_from = (PyObject *(*)(struct __pyx_obj_11Cython_test_7sources_main_class_3 *, main_class &&))__pyx_f_11Cython_test_7sources_8main_class_3_move_from;
^
sources.cpp:5121:75: error: expected primary-expression before ‘struct’
__pyx_vtable_11Cython_test_7sources_main_class_3.move_from = (PyObject *(*)(struct __pyx_obj_11Cython_test_7sources_main_class_3 *, main_class &&))__pyx_f_11Cython_test_7sources_8main_class_3_move_from;
^
sources.cpp:5121:133: error: expected primary-expression before ‘&&’ token
__pyx_vtable_11Cython_test_7sources_main_class_3.move_from = (PyObject *(*)(struct __pyx_obj_11Cython_test_7sources_main_class_3 *, main_class &&))__pyx_f_11Cython_test_7sources_8main_class_3_move_from;
但所有這些令牌與我創建的C++對象移動到蟒蛇的對象。任何其他聲明都沒有錯誤。
有人可以幫助告訴我我錯在哪裏嗎?
這可能是有用的:http://intermediate-and-advanced-software-carpentry.readthedocs.io/en/latest/c++-wrapping.html – Alexander
你確定它使用C++ 11模式(或更高版本)編譯時。對於gcc,你可能會添加像'extra_link_args = [' - std = C++ 11']'到'setup.py' http://stackoverflow.com/questions/1676384/how-to-pass-flag-to- gcc-in-python-setup-py-script – DavidW
如果一個cython方法能夠返回一個內存視圖,那麼就不會複製(也許這是[question](http://stackoverflow.com/questions/36357024/wrapping) -stdarray-in-cython-and-exposeing-memory-views-views)) –