我正在学习如何通过制作包装器从 Python 调用 C 函数。我的最终目标是将 Python 中声明的巨大复杂数组传递给我的 C 函数,并返回其他巨大复杂数组。
我从一个简单的示例开始,以了解从 Python 调用 C 函数的基础知识。我定义了一个函数,该函数读取 double 组(任何大小)并返回所有值的总和。这是我的wrapperTest.c代码:
#include <Python.h>
static PyObject *sumArray(PyObject * self, PyObject * args){
PyObject *ret;
PyObject* myTuple;
if(!PyArg_ParseTuple(args, "O", &myTuple)) return NULL;
printf("PyTuple_Size=%ld\n", PyTuple_Size(myTuple));
double *my_array;
my_array=(double*)malloc(sizeof(double)*PyTuple_Size(myTuple));
int tupleSize;
tupleSize=PyTuple_Size(myTuple);
int i;
PyObject* tupleItem;
for(i=0; i<tupleSize; i++){
tupleItem=PyTuple_GetItem(myTuple, i);
if(!PyFloat_Check(tupleItem)){
printf("Error: tuple contains a non-float value");
exit(1);
}
my_array[i]=PyFloat_AsDouble(tupleItem);
printf("my_array[%d]=%lf\n", i, my_array[i]);
}
double result;
result=0.;
for(i=0; i<tupleSize; i++){
result+=my_array[i];
}
printf("result=%lf\n", result);
ret=PyFloat_FromDouble(result);
free(my_array);
return ret;
}
static PyMethodDef wrapperTest_funcs[] = {
{"sumArray", (PyCFunction)sumArray,
METH_VARARGS, ""},
{NULL}
};
void initwrapperTest(void)
{
Py_InitModule3("wrapperTest", wrapperTest_funcs,
"Extension module example!");
}
我可以通过运行脚本 setup.py 成功编译扩展
from distutils.core import setup, Extension
setup(name='wrapperTest', version='1.0', \
ext_modules=[Extension('wrapperTest', ['wrapperTest.c'])])
使用命令“python setup.py install”。此外,我可以在运行 Python 时导入扩展并执行该函数。但是,我无法从定义的函数中始终获得正确的结果。例如,如果我尝试传递数组 a=(1.2, 2.4),这就是我得到的:
>>> import wrapperTest
>>> a=(1.2, 2.4)
>>> b=wrapperTest.sumArray(a)
PyTuple_Size=2
my_array[0]=1.200000
my_array[1]=2.400000
result=3.600000
>>> b
3.5999999999999996
显然正确的结果是3.6(C语言编写的函数打印的结果),但Python中最终得到的结果是3.5999999999999996。当然,它非常接近正确的结果,但又不一样。我错过了什么?
最佳答案
我认为 printf 输出的默认精度是 6 位小数。
是否只是您的 printf 函数将答案四舍五入为 3.600000 并且 python 的打印更加准确?
关于python - 在从 Python 调用的 C 函数中使用 PyFloat_FromDouble 时获得错误结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30866183/