从Python调用C函数返回值的问题

9

我有一个看似简单的问题需要解决。我需要从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;
}

在我的实际测试函数中,我打印val1val2以确保它们接收到了值。在这方面一切都很好。调用此函数的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不喜欢返回的结果。
你有什么主意吗?
1个回答

16

在Python中,您应该使用argtypesrestype成员设置函数的参数类型和返回类型:

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教程,其中包含许多有用信息。

非常感谢您提供的解决方案和链接。这个教程正是我一直在寻找的! - lively

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接