О, мое слово, я дурак. При вызове функции я просто опускал второй и третий аргументы. Как дурак. Потому что я такой. Исходный глупый вопрос следует:
Кажется, что это должно быть очень распространенным явлением, но я не могу найти соответствующий учебник, и я слишком незнаю о Numpy
и ctypes
, чтобы понять это сам.
У меня есть функция C в файле ctest.c
.
#include <stdio.h>
void cfun(const void * indatav, int rowcount, int colcount, void * outdatav) {
//void cfun(const double * indata, int rowcount, int colcount, double * outdata) {
const double * indata = (double *) indatav;
double * outdata = (double *) outdatav;
int i;
puts("Here we go!");
for (i = 0; i < rowcount * colcount; ++i) {
outdata[i] = indata[i] * 2;
}
puts("Done!");
}
(Как вы можете догадаться, у меня изначально были аргументы как double *, а не void *, но я не мог понять, что делать с Python. Конечно, я бы хотел их изменить, но я не придирчивый, пока он работает.)
Я делаю из него общую библиотеку. gcc -fPIC -shared -o ctest.so ctest.c
Затем в Python у меня есть несколько массивов numpy, и я хотел бы передать их функции C, один как входной и один в качестве вывода.
indata = numpy.ones((5,6), dtype=numpy.double)
outdata = numpy.zeros((5,6), dtype=numpy.double)
lib = ctypes.cdll.LoadLibrary('./ctest.so')
fun = lib.cfun
# Here comes the fool part.
fun(ctypes.c_void_p(indata.ctypes.data), ctypes.c_void_p(outdata.ctypes.data))
print 'indata: %s' % indata
print 'outdata: %s' % outdata
Это не сообщает о каких-либо ошибках, но выводит
>>> Here we go!
Done!
indata: [[ 1. 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1. 1.]]
outdata: [[ 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0.]]
Массив outdata не изменяется. И на самом деле, если я снова вызову функцию, получим segfault. Меня это не удивляет - я действительно не знаю, что я здесь делаю. Может ли кто-нибудь указать мне в правильном направлении?