2013-04-18 3 views
3

Я пытаюсь перенести некоторый код MatLab с расширениями Mex в Python с numpy и scipy-библиотеками. Используя этот замечательный учебник http://www.scipy.org/Cookbook/C_Extensions/NumPy_arrays, я довольно быстро принимаю C-функции для вызова из Python. Но некоторые C-функции вызывают функции MatLab, поэтому я должен подставить этот код, вызвав функции numpy и scipy из C-кода.Вызов функции numpy из C-кода

Я попытался сделать что-то подобное Extending and Embedding the Python Interpreter. Однако я столкнулся с проблемой: как передать массив в аргумент функции. Более того, этот длинный путь найти функцию в модуле, а затем построить кортеж для аргументов не кажется очень элегантным.

Итак, как вызвать функцию sum в модуле numpy из C-кода, например?

Буду признателен за любые идеи или ссылки. Ruben

P.S. Вот пример:

PyObject *feedback(PyObject *self, PyObject *args){ 
    PyArrayObject *Vecin; 
    double mp=0,ret; 
    if(!PyArg_ParseTuple(args,"O!d",&PyArray_Type,&Vecin,&mp) 
     || Vecin == NULL) return NULL; 
    /* make python string with module name */ 
    PyObject *pName = PyString_FromString("numpy"); 
    if(pName == NULL){ 
     fprintf(stderr,"Couldn\'t setup string %s\n","numpy"); 
     return NULL; 
    } 
    /* import module */ 
    PyObject *pModule = PyImport_Import(pName); 
    Py_DECREF(pName); 
    if(pModule == NULL){ 
     fprintf(stderr,"Couldn\'t find module %s\n","numpy"); 
     return NULL; 
    } 
    /* get module dict */ 
    PyObject *dic = PyModule_GetDict(pModule); 
    if(dic == NULL){ 
     fprintf(stderr,"Couldn\'t find dic in module %s\n","numpy"); 
     return NULL; 
    } 
    /* find function */ 
    PyObject *pFunction = PyDict_GetItemString(dic, "sum"); 
    Py_DECREF(dic); 
    if(pFunction == NULL){ 
     fprintf(stderr,"Couldn\'t find function %s in dic\n","sum"); 
     return NULL; 
    } 
    Py_DECREF(pModule); 
    /* create typle for new function argument */ 
    PyObject *inarg = PyTuple_New(1); 
    if(inarg == NULL){ 
     fprintf(stderr,"Cannot convert to Build in Value\n"); 
     return NULL; 
    } 
    /* set one input paramter */ 
    PyTuple_SetItem(inarg, 0, (PyObject*)Vecin); 
    /* call sunction from module and get result*/ 
    PyObject *value = PyObject_CallObject(pFunction, inarg); 
    if(value == NULL){ 
     fprintf(stderr,"Function return NULL pointer\n"); 
     return NULL; 
    } 
    Py_DECREF(pFunction); 
    if(!PyArg_ParseTuple(value,"d",&ret)) return NULL; 
    return Py_BuildValue("d",ret*mp); 
} 

Результат

>>print mymod.FeedBack(np.array([1.,2.,3.,4.,5.]),2) 


Traceback (most recent call last): 
    File "mymodtest.py", line 10, in <module> 
    print mymod.FeedBack(np.array([1.,2.,3.,4.,5.]),2) 
SystemError: new style getargs format but argument is not a tuple 
Segmentation fault 
+0

это поможет вам: http://stackoverflow.com/a/15670672/ 1031417? – 0x90

+0

@ 0x90, вероятно, нет. Я не использую никаких оболочек или предтранслиляторов от python до c, потому что исходный код в расширениях mex является c-кодом. – rth

+0

Использует [Cython] (http://cython.org) вариант? Он поддерживает специальную поддержку NumPy, и работать с ним гораздо проще, чем API Python C. –

ответ

1

NumPy C API имеет PyArray_Sum:

PyObject *sum = PyArray_Sum(arr, NPY_MAXDIMS, PyArray_DESCR(arr)->type_num, NULL); 
+0

Приятно, спасибо. Но сумма-функция просто пример. Как насчет любой другой функции в numpy и scipy? У всех у них есть API C? Это действительно озадачивает меня, как формировать кортеж входных аргументов для функций numpy/scipy с массивами. – rth

+0

@rth вы формируете кортеж входных аргументов, как и любая другая функция Python, или просто используйте 'PyObject_CallFunctionObjArgs'. – ecatmur

+0

@eatmur Я изменил в своем примере выше значение 'PyObject * = PyObject_CallObject (pFunction, inarg);' to 'PyObject * value = PyObject_CallFunctionObjArgs (pFunction, Vecin, NULL);' и возвращает 'SystemError: новый стиль getargs формат, но аргумент не является кортежем Ошибка сегментации – rth

 Смежные вопросы

  • Нет связанных вопросов^_^