【发布时间】:2013-04-18 03:30:34
【问题描述】:
我正在尝试将一些带有 Mex 扩展的 MatLab 代码移动到带有 numpy 和 scipy 库的 Python 中。使用这个精彩的教程http://www.scipy.org/Cookbook/C_Extensions/NumPy_arrays,我很快就采用了 C 函数来从 Python 调用。但是有些 C 函数调用 MatLab 函数,所以我必须通过从 C 代码调用 numpy 和 scipy 函数来替换这段代码。
我尝试过类似Extending and Embedding the Python Interpreter 的操作。但是,我遇到了一个问题:如何将数组传递给函数参数。此外,在模块中查找函数然后为参数构建元组的这种漫长的方法似乎不是很优雅。
那么,例如,如何在 C 代码中调用 numpy 模块中的 sum 函数?
如果有任何想法或链接,我将不胜感激。 鲁本
附:举个例子:
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
【问题讨论】:
-
对你有帮助吗:stackoverflow.com/a/15670672/1031417 ?
-
@0x90 可能不是。我不使用任何包装器或预翻译器,从 python 到 c,因为 mex 扩展中的原始代码是 c 代码。
-
是否使用Cython 选项?它对 NumPy 有特殊的支持,并且比 Python C API 更容易使用。
-
@larsmans。我知道了,谢谢!问题出在为 MatLab 作为 mex 模块编写的 c 代码中。我想保持这段代码完整。
-
@rth:你可以用 Cython 包装 C 代码。
标签: python numpy python-c-api python-c-extension