さて、私はこれを味わうことができるようにこれを終えるのにとても近いです。過去数週間ほど、Cythonを介してC++で記述されたライブラリとインターフェイスするPython拡張機能を作成しようとしてきました。ここの人たちと数人の友人の助けを借りて、私はそこまでの道のりの98%のように感じるものをなんとか手に入れることができました。残っているのはこれだけです。署名されていないshortの配列へのポインターをPythonオブジェクト(できればリスト)に変換する方法を私は一生理解できません。
少し背景がありますが、コールバック関数を設定するライブラリの一部とインターフェイスしようとしています。これは、これで正常に実行されました。
global callbackfunc
ctypedef unsigned short const_ushort "const uint16_t"
ctypedef void (*Function1)(const_ushort *data, unsigned width, unsigned height)
cdef extern from "lib.hpp":
void SetCallback(Function1)
cdef void cSetCallback(Function1 function):
SetCallback(function)
cdef void callcallback(const_ushort *data, unsigned width, unsigned height):
global callbackfunc
callbackfunc(data,width,height)
cSetCallback(callcallback)
def PySetCallback(callbackFunc):
global callbackfunc
callbackfunc = callbackFunc
この問題は関数「callcallback」内で発生し、「'const_ushort*'をPythonオブジェクトに変換できません」というエラーが表示されます。これを回避する最初の試みは、新しいpythonリストを作成し、ループして配列の各要素を次のようにpythonリストに入れることでした。
datalist = []
for i in range(width*height):
datalist += data[i]
悲しいことに、これは、型を「const const unsigned short」として定義しようとしているコンパイル済みのcythonコードで私を悩ませますが、これは明らかに問題です。
それから私はこれを試しました:
datalist = []
for i in data:
datalist += i
これにより、「C配列の反復には既知の終了インデックスが必要です」と表示されます。私はC/C ++をほとんど知らないので、これのほとんどは私にはあまり意味がないことに注意してください。
それで、とにかく、そのようなポインタをpythonオブジェクトに変換する効果的な方法はありますか(通常は約57344アイテムであり、これは非常に時間に敏感なので、配列をループするよりも高速です)
編集:もう少し明確にすると、私はコールバックを使用しています。これを呼び出すライブラリ内のC ++関数は、「const uint_16」の配列へのポインターを送信します。そのため、const_ushortをそのように定義しました。そうしないと、型が統一されないためです。ライブラリを変更することはできません。
Edit2:わかったようです。私がしなければならなかったのは、const unsigned shortsの配列ではなく、unsigned shortsの配列として配列を明示的にキャストすることでした。これにより、非定数でインデックスを付けることができました。これを実現するために、私はこのような別のC ++関数を作成しました(他の誰かが私のためにそれを書いた、私はC ++をほとんど知らない):
unsigned short *convert_short(const unsigned short *test){ return const_cast<unsigned short *>(test); }
これにより、クラス内に「 getindex 」関数を作成し、関数に基づいて正しい値を返すことができました。そうですね、Pythonは配列を正しく読み取っているようですが、そうではないので、このケースは閉じているようです。どうもありがとう。