как вызвать c-функцию, ожидающую указатель на структуру с ctypes? - PullRequest
1 голос
/ 12 августа 2011

Я сталкиваюсь со следующей проблемой.В CI написали следующее:

#include <stdio.h>
typedef struct {
double *arr;
int length;
} str;

void f(str*);

int main (void){
   double x[3] = {0.1,0.2,0.3};
   str aa;
   aa.length = 3;
   aa.arr = x;
   f(&aa);
   return 0;
}

void f(str *ss){
   int i;
   printf("%d\n",ss->length);
   for (i=0; i<ss->length; i++) {
      printf("%e\n",ss->arr[i]);
   }
}

Если я скомпилирую его в исполняемый файл, он будет работать правильно.Я получаю:

 3
 0.1
 0.2
 0.3

как и должно быть.После построения разделяемой библиотеки 'pointertostrucCtypes.so' из вышеприведенного C-кода я вызываю функцию f в python следующим образом:

ptrToDouble = ctypes.POINTER(ctypes.c_double)
class pystruc (ctypes.Structure):
   _fields_=[
             ("length",ctypes.c_int),
             ("arr",ptrToDouble)
            ]
aa = pystruc()
aa.length = ctypes.c_int(4)
xx = numpy.arange(4,dtype=ctypes.c_double)
aa.arr = xx.ctypes.data_as(ptrToDouble)
myfunc = ctypes.CDLL('pointertostrucCtypes.so')
myfunc.f.argtypes = [ctypes.POINTER(pystruc)]

myfunc.f(ctypes.byref(aa))

В результате она всегда выводит произвольное целое число, а затем даетошибка сегментации.потому что длина не подходит.Кто-нибудь знает, что я делаю не так?

1 Ответ

3 голосов
/ 12 августа 2011

Ваши поля поменялись местами. Попробуйте:

class pystruc (ctypes.Structure):
    _fields_=[
             ("arr",ptrToDouble)
             ("length",ctypes.c_int),
            ]
...