Вопрос по ctypes, python – Ошибка возврата значений из C-функции, вызываемой из Python

9

У меня трудности с кажущейся простой проблемой. Существуют различные функции C, которые мне нужно вызывать из кода Python. В настоящее время я пытаюсь сделать это с помощью 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 возвращается и печатается, как и ожидалось. Если я установлю его на удвоение, вычисления верны в коде C (я печатаю их для проверки), но Python не нравится возвращаемый результат.

Есть идеи, что мне не хватает?

Ваш Ответ

1   ответ
13

Вы должны установить типы аргументов функции и тип возвращаемого значения в 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.

Смотрите также этоучебник по типамУ него есть много полезной информации.

Большое спасибо за решение и ссылку. Учебник - это именно то, что я искал! lively

Похожие вопросы