23
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ますか?

4

4 に答える 4

10

CコードをPythonクラスとして構造体でラップしようとして、この問題に遭遇しました。問題は、 を含む「特別な」関数のようであり、ではなくとして宣言する必要があり__init__ます。これは、通常の python から呼び出すことができることを意味するため、型パラメーターは事実上無視され、すべてがオブジェクトとして扱われます。__cinit__defcdef

JF Sebastian の回答では、修正はラッピングではありません。double は基本的な数値型であるため、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
于 2014-05-01T20:33:15.253 に答える
5

各 cdef クラスに対して、コンストラクターとして機能するグローバル cdef 関数を作成します。CefResponse は C++ オブジェクトであり、PyResponse は c++ オブジェクトに相当する Python です。

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)したがって、 callの代わりにresp = CreatePyResponse(cppObject).

CEF Python からの例: https://code.google.com/p/cefpython/source/browse/cefpython/response.pyx?r=0250b65e046a

于 2012-08-30T20:55:40.233 に答える
1

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インスタンスは、Cython と純粋な Python の両方から、他の Python オブジェクトとして使用できます。

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

print(PyClass(PyBar(1)).bar.d)
于 2012-09-01T22:45:41.447 に答える