2012-08-03 171 views
7

我看起来很简单的问题有困难。我需要从Python代码调用各种C函数。目前,我试图通过ctypes来做到这一点。我遇到了一个简单的示例实现问题,我正在使用它来确保在更改大量现有代码之前,一切都按预期工作。 C函数需要几个参数,进行各种数学计算,然后返回一个double值。这是我用作测试的C文件。从Python函数调用Python返回值

#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不喜欢返回的结果。

任何想法我失踪?

回答

9

您应该设置函数的参数类型和使用argtypesrestype成员在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,它有很多有用的信息。

+0

非常感谢您的解决方案和链接。该教程正是我一直在寻找的! – lively 2012-08-03 21:10:30