我很难解决一个看似简单的问题。我需要从Python代码中调用各种C函数。目前,我正在尝试通过ctypes做到这一点。我在使用一个简单的示例实现时遇到了问题,该示例实现用于确保在更改现有代码的大块之前一切都能按预期工作。C函数采用一些参数,进行各种数学计算,然后返回一个双精度值。这是我用作测试的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不喜欢返回的结果。
有什么想法我想念的吗?
您应该使用argtypes和restype成员在Python中设置函数的参数类型和返回类型:
argtypes
restype
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.c_double * length)
result
double
另请参阅本ctypes教程,它具有许多有用的信息。