2012-08-03 11 views
7

Tengo dificultades con un problema aparentemente simple. Hay varias funciones de C que necesito llamar desde el código de Python. Actualmente, estoy tratando de hacer esto a través de ctypes. Tengo problemas con una implementación de ejemplo simple que estoy usando para garantizar que todo funcione según lo previsto antes de cambiar grandes fragmentos de código existente. Las funciones C toman algunos parámetros, hacen varios cálculos matemáticos y luego devuelven un valor doble. Este es el archivo C que estoy usando como prueba.Problema al devolver valores de la función C llamada desde 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; 
} 

En mi función de prueba real que estoy imprimiendo val1 val2 y para asegurar que están recibiendo valores. Todo está bien en ese extremo. El Python que llama a esta función es el siguiente.

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 

Cuando esto imprime el resultado devuelto, por lo general vuelca un número negativo grande. Mi hipótesis es que necesito hacer algunas conversiones antes de que Python pueda manejar el valor, pero no puedo encontrar una respuesta para eso por mi vida. He buscado por siempre, pero no estoy seguro de si me falta lo obvio o de buscar la información incorrecta.

Además, si cambio el tipo de devolución de la función a int, los cálculos resultan correctos y se devuelve un int e imprimió como se esperaba. Si lo configuro en el doble, los cálculos son correctos en el código C (los imprimo para verificar), pero a Python no le gusta el resultado devuelto.

¿Alguna idea de lo que me estoy perdiendo?

Respuesta

9

Debe establecer los tipos de argumentos de la función y el tipo de retorno en Python usando los argtypes y restype miembros:

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 

A continuación, se puede llamar así que estás haciendo: construir matrices de tipo (ctypes.c_double * length) inicializados con sus valores , y el result será un double.

Consulte también este ctypes tutorial, tiene mucha información útil.

+0

Muchas gracias por la solución y el enlace. ¡El tutorial es exactamente lo que he estado buscando! – lively

Cuestiones relacionadas