Пример Numpy C-Api выдает ошибку SegFault

#python #c #numpy #python-c-api

#python #c #numpy #python-c-api

Вопрос:

Я пытаюсь понять, как работает Python C- Api, и я хочу обмениваться массивами numpy между Python и расширением C.

Итак, я начал этот урок:http://dsnra.jpl.nasa.gov/software/Python/numpydoc/numpy-13.html

Попытался выполнить первый пример там, модуль C, который вычисляет трассировку 2d массива numpy, был очень аккуратным для меня, так как я хочу выполнять элементарные операции и в 2d массивах.

 #include <Python.h>
#include "Numeric/arrayobject.h"
#include<stdio.h>

int main(){
Py_Initialize();
import_array();
}

static char doc[] =
"This is the C extension for xor_masking routine";

    static PyObject *
    trace(PyObject *self, PyObject *args)
    {
    PyObject *input;
    PyArrayObject *array;
    double sum;
    int i, n;

    if (!PyArg_ParseTuple(args, "O", amp;input))
    return NULL;
    array = (PyArrayObject *)
    PyArray_ContiguousFromObject(input, PyArray_DOUBLE, 2, 2);
    if (array == NULL)
    return NULL;

    n = array->dimensions[0];
    if (n > array->dimensions[1])
    n = array->dimensions[1];
    sum = 0.;
    for (i = 0; i < n; i  )
    sum  = *(double *)(array->data   i*array->strides[0]   i*array->strides[1]);
    Py_DECREF(array);
    return PyFloat_FromDouble(sum);
    }

static PyMethodDef TraceMethods[] = {
    {"trace", trace, METH_VARARGS, doc},
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
inittrace(void)
{
    (void) Py_InitModule("trace", TraceMethods);
}


}
  

Имя модуля — trace, и он скомпилирован с setup.py файл:

 from distutils.core import setup, Extension

module = Extension('trace', sources = ['xor_masking.cpp'])
setup(name = 'Trace Test', version = '1.0', ext_modules = [module])
  

Файл скомпилирован, trace.so импортируется в IPython, но когда я пытаюсь использовать метод trace(), я получаю ошибку сегментации, я не знаю почему.

Я запускаю это с Fedora 15, Python 2.7.1, gcc 4.3.0, Numpy 1.5.1

Комментарии:

1. Обратите внимание, что руководство, которому вы следуете, предназначено для Numeric , старой библиотеки, замененной текущей Numpy. Numpy в основном обратно совместим с ним, но не полностью. (Да, также Numeric неофициально назывался «Numpy», что приводит к путанице …)

2. Тогда, должен ли я импортировать #include "Numpy/arrayobject.h вместо этого?

Ответ №1:

Ваша функция инициализации для модуля должна вызывать

 import_array();
  

после

 (void) Py_InitModule("trace", TraceMethods);
  

Об этом упоминается в руководстве вверху, но это легко пропустить. Без этого это приводит к сбоям PyArray_ContiguousFromObject .

Комментарии:

1. Большое спасибо! Да, мне было трудно понять инициализацию. Это работает как шарм.

2. Вау. Я ломал голову над этим! Спасибо

3. Для более новой версии: добавьте import_array(); перед Py_Initialize();