我遇到了一个看似简单的问题。我需要从Python代码调用各种C函数。目前,我正试图通过ctypes来做到这一点。我遇到了一个简单的示例实现的问题,我正在使用它来确保在更改大块现有代码之前一切都按预期工作。 C函数采用一些参数,进行各种数学计算,然后返回一个double值。这是我用作测试的C文件。
#include "Python.h"
double eval(double* args, int length, double* rands, int randLength, int debug)
{
double val1 = args[0];
double val2 = rands[0];
double ret = val1 + val2;
return ret;
}
在我的实际测试功能中,我打印 val1 和 val2 以确保它们正在接收值。一切都很好。调用此函数的Python如下所示。
test = ctypes.CDLL("/home/mjjoyce/Dev/C2M2L/AquaticWavesModel.so")
rand = Random();
args = [2]
argsArr = (ctypes.c_double * len(args))()
argsArr[:] = args
argsRand = [rand.random()]
argsRandArr = (ctypes.c_double * len(argsRand))()
rgsRandArr[:] = argsRand
result = test.eval(argsArr, len(argsArr), argsRandArr, len(argsRandArr), 0)
print "result", result
当打印返回的结果时,它通常会转储一个较大的负数。这是我的假设,我需要在Python处理该值之前进行一些转换,但是我无法找到适合我生活的答案。我一直在搜索,但我不确定我是否错过了明显的信息,或者搜索错误的信息。
此外,如果我将函数的返回类型更改为int,则计算结果正确并返回int并按预期打印。如果我将它设置为double,则C代码中的计算是正确的(我打印它们进行检查),但Python不喜欢返回的结果。
我缺少什么想法?
答案 0 :(得分:13)
您应该使用argtypes
和restype
成员在Python中设置函数的参数类型和返回类型:
test.eval.argtypes = [ctypes.POINTER(ctypes.c_double),
ctypes.c_int,
ctypes.POINTER(ctypes.c_double),
ctypes.c_int,
ctypes.c_int]
test.eval.restype = ctypes.c_double
然后你可以像你正在做的那样调用它:构造用你的值初始化的(ctypes.c_double * length)
类型的数组,result
将是double
。
另见ctypes tutorial,它有很多有用的信息。