通过C ++指针作为参数转换为用Cython功能(Passing C++ pointer as ar

2019-07-31 06:38发布

cdef extern from "Foo.h":
    cdef cppclass Bar:
        pass

cdef class PyClass:
    cdef Bar *bar

    def __cinit__(self, Bar *b)
        bar = b

这将始终给我这样的:
Cannot convert Python object argument to type 'Bar *'

有没有办法做到这一点,或者我需要从提取的一切Bar对象,创建一个Python等同的,通过它,然后重建它在PyClass

Answer 1:

我遇到了这个问题,试图总结的C代码结构的Python类。 这个问题似乎是“特殊”的功能,包括__init____cinit__必须声明为def ,而不是cdef 。 这意味着,他们可以从正常的蟒蛇被调用,因此类型参数实际上被忽略,一切都被视为对象。

在JF Sebastian的答案的解决方法是不缠绕 - 双是一个基本的数字型等存在C / C ++类型和Python对象之间的缺省转换。 Czarek的答案基本上是正确 - 你需要使用一个假的构造函数用法,使用全局函数。 这是不可能使用@staticmethod装饰因为它们不能被应用到CDEF功能。 答案看起来提供的原始例子简单。

cdef extern from "Foo.h":
    cdef cppclass Bar:
        pass

cdef class PyClass:
    cdef Bar *bar

cdef PyClass_Init(Bar *b):
    result = PyClass()
    result.bar = b
    return result


Answer 2:

由于用Cython 0.21已经可以宣布cdef与方法@staticmethod装饰。 这使得采取非Python的参数静态创作者的方法:

cdef extern from "Foo.h":
    cdef cppclass Bar:
        pass

cdef class PyClass:
    cdef Bar *bar

    @staticmethod
    cdef create(Bar *bar):
        cdef PyClass pc = PyClass()
        pc.bar = bar
        return pc


Answer 3:

对于每一个类CDEF创建充当构造全局CDEF功能,CefResponse是一个C ++对象,PyResponse一个python等效C ++对象的:

cdef object CreatePyResponse(CefRefPtr[CefResponse] cefResponse):

    pyResponse = PyResponse()
    pyResponse.cefResponse = cefResponse
    return pyResponse

cdef class PyResponse:

    cdef CefRefPtr[CefResponse] cefResponse

    def GetStatus(self):

        return (<CefResponse*>(self.cefResponse.get())).GetStatus()

因此,而不是resp = PyResponse(cppObject)调用resp = CreatePyResponse(cppObject)

例如,从CEF的Python采取: https://code.google.com/p/cefpython/source/browse/cefpython/response.pyx?r=0250b65e046a



Answer 4:

Python类的Python接受的论点。 要通过你需要用它一个C ++的说法:

# distutils: language = c++

cdef extern from "Foo.h" namespace "baz":
    cdef cppclass Bar:
         Bar(double d)
         double get()

cdef class PyBar: # wrap Bar class
    cdef Bar *thisptr
    def __cinit__(self, double d):
        self.thisptr = new Bar(d)
    def __dealloc__(self):
        del self.thisptr
    property d:
        def __get__(self):
            return self.thisptr.get()

PyBar实例可以被用作任何其他的Python无论从用Cython和纯Python对象:

class PyClass:
    def __init__(self, PyBar bar):
        self.bar = bar

print(PyClass(PyBar(1)).bar.d)


文章来源: Passing C++ pointer as argument into Cython function
标签: python cython