私はCythonを使わずにPython C-Extensionを書いています。C配列からPyArray
私はC言語で二重配列を割り当て、それを内部関数(Fortran内にある)で使用して返したいと思います。私はCとFortranのインタフェースが、私はこのコードをデバッグC.
static PyObject *
Py_drecur(PyObject *self, PyObject *args)
{
// INPUT
int n;
int ipoly;
double al;
double be;
if (!PyArg_ParseTuple(args, "iidd", &n, &ipoly, &al, &be))
return NULL;
// OUTPUT
int nd = 1;
npy_intp dims[] = {n};
double a[n];
double b[n];
int ierr;
drecur_(n, ipoly, al, be, a, b, ierr);
// Create PyArray
PyObject* alpha = PyArray_SimpleNewFromData(nd, dims, NPY_DOUBLE, a);
PyObject* beta = PyArray_SimpleNewFromData(nd, dims, NPY_DOUBLE, b);
Py_INCREF(alpha);
Py_INCREF(beta);
return Py_BuildValue("OO", alpha, beta);
}
で完璧に動作することを指摘し、私は外のアルファを作成しようとすると、私はセグメンテーションフォールトを取得します。それまではすべて正常に動作します。関数drecur_は機能し、削除されても同じ問題が発生します。
ここで、Cデータの周りにPyArrayを定義する標準的な方法は何ですか?私はドキュメンテーションが見つかりましたが、良い例はありません。また、メモリリークはどうですか?アルファとベータのインスタンスが保持されるように、戻りの前にINCREFするのは正しいですか?彼らがもはや必要でない時の割り当て解除はどうですか?
編集 最終的にNumPy cookbookにあるアプローチで正しく取得できました。
static PyObject *
Py_drecur(PyObject *self, PyObject *args)
{
// INPUT
int n;
int ipoly;
double al;
double be;
double *a, *b;
PyArrayObject *alpha, *beta;
if (!PyArg_ParseTuple(args, "iidd", &n, &ipoly, &al, &be))
return NULL;
// OUTPUT
int nd = 1;
int dims[2];
dims[0] = n;
alpha = (PyArrayObject*) PyArray_FromDims(nd, dims, NPY_DOUBLE);
beta = (PyArrayObject*) PyArray_FromDims(nd, dims, NPY_DOUBLE);
a = pyvector_to_Carrayptrs(alpha);
b = pyvector_to_Carrayptrs(beta);
int ierr;
drecur_(n, ipoly, al, be, a, b, ierr);
return Py_BuildValue("OO", alpha, beta);
}
double *pyvector_to_Carrayptrs(PyArrayObject *arrayin) {
int n=arrayin->dimensions[0];
return (double *) arrayin->data; /* pointer to arrayin data as double */
}
これに感謝し、答えに感謝します。