Cython:通过参考传递

时间:2015-03-30 21:13:26

标签: python c++ pass-by-reference cython

问题

我想通过引用Cython传递一个向量。

cdef extern from "MyClass.h" namespace "MyClass":
    void MyClass_doStuff "MyClass::doStuff"(vector[double]& input) except +

cdef class MyClass:

...

@staticmethod
def doStuff(vector[double]& input):
    MyClass_doStuff(input)

问题

上面的代码在编译过程中不会抛出错误,但它也无法正常工作。方法后,input根本没有变化。 我也尝试过推荐in this question,但在这种情况下,cdef - 函数无法通过Python访问("未知成员doStuff ......")。 / p>

是否可以通过引用传递,如果是,如何正确地进行?

修改

这不是cython-c-passing-by-reference的重复,因为我在上面的部分中提到了这个问题。建议的解决方案无法实现我的目标: python 函数通过引用获取参数。

1 个答案:

答案 0 :(得分:2)

问题

正如Kevin和jepio在你的问题的评论中所说的那样,麻烦就是如何处理Python中的向量。 Cython确实定义了一个cpp向量类,它自动转换为边界列表中的/从Cython代码转换为。

问题在于转换步骤:调用函数时:

def doStuff(vector[double]& input):
    MyClass_doStuff(input)

转换为接近

的东西
def doStuff(list input):
    vector[double] v= some_cython_function_to_make_a_vector_from_a_list(input)
    MyClass_doStuff(input)
    # nothing to copy the vector back into the list

答案

我认为你有两种选择。第一种方法是完整地编写流程(即做两份手册):

def doStuff(list input):
  cdef vector[double] v = input
  MyClass_doStuff(v)
  input[:] = v

这对于大型载体来说会很慢,但适合我(我的测试函数是v.push_back(10.0)):

>>> l=[1,2,3,4]
>>> doStuff(l)
>>> l
[1.0, 2.0, 3.0, 4.0, 10.0]

第二个选项是定义直接包含vector[double]

的自己的包装类
cdef class WrappedVector:
  cdef vector[double] v
  # note the absence of:
  #   automatically defined type conversions (e.g. from list)
  #   operators to change v (e.g. [])
  #   etc.
  # you're going to have to write these yourself!

然后写

def doStuff(WrappedVector input):
  MyClass_doStuff(input.v)