この質問は、私が以前に尋ねた質問に関連しています。つまり、誰かが興味を持っているならこれ。基本的に、私がやりたいのは、 -objectでPy_buffer
ラップされたものを使用してC配列をPythonに公開することです。memoryview
(work = Pythonでデータを操作し、Cでstdoutに書き込むことができます)を使用して動作するようになりましPyBuffer_FillInfo
たが、自分のバッファーをロールしようとすると、C関数が戻った後にセグメンテーション違反が発生します。
PyBuffer_FillInfoはフォーマットがcharであると想定し、itemsizeフィールドを1にするため、独自のバッファーを作成する必要があります。サイズ1、2、4、および8のアイテムを提供できる必要があります。
いくつかのコード、これは実用的な例です:
Py_buffer *buf = (Py_buffer *) malloc(sizeof(*buf));
int r = PyBuffer_FillInfo(buf, NULL, malloc(sizeof(char) * 4), 4, 0, PyBUF_CONTIG);
PyObject *mv = PyMemoryView_FromBuffer(buf);
//Pack the memoryview object into an argument list and call the Python function
for (blah)
printf("%c\n", *buf->buf++); //this prints the values i set in the Python function
PyBuffer_FillInfo
非常に単純なの実装を見て、カスタムアイテムサイズを提供できるように独自の関数をロールしました。
//buffer creation function
Py_buffer *getReadWriteBuffer(int nitems, int itemsize, char *fmt) {
Py_buffer *buf = (Py_buffer *) malloc(sizeof(*buf));
buf->obj = NULL
buf->buf = malloc(nitems * itemsize);
buf->len = nitems * itemsize;
buf->readonly = 0;
buf->itemsize = itemsize;
buf->format = fmt;
buf->ndim = 1;
buf->shape = NULL;
buf->strides = NULL;
buf->suboffsets = NULL;
buf->internal = NULL;
return buf;
}
使い方:
Py_buffer *buf = getReadWriteBuffer(32, 2, "h");
PyObject *mv = PyMemoryView_FromBuffer(buf);
// pack the memoryview into an argument list and call the Python function as before
for (blah)
printf("%d\n", *buf->buf); //this prints all zeroes even though i modify the array in Python
return 0;
//the segfault happens somewhere after here
私自身のバッファオブジェクトを使用した結果は、C関数が戻った後のセグメンテーション違反です。なぜこれが起こるのか、私は本当に理解していません。どんな助けでも大歓迎です。
編集私が以前に見つけられなかったこの質問に
よると、itemsize>1はまったくサポートされていない可能性があります。これにより、この質問はさらに興味深いものになります。たぶん、私がPyBuffer_FillInfo
欲しいものを保持するのに十分な大きさのメモリブロックで使用できます(たとえば、32 Cフロート)。その場合、問題はmemoryview
、Python関数でオブジェクトにPythonフロートを割り当てる方法に関するものです。質問質問。