Я пытаюсь построить интерфейс python вокруг некоторых существующих C code с CFFI. Как обычно, с C-кодом, обрезанным для производительности, он чреват обширными макросами и typedef.Создание cdata типа `REAL (* vertices) [DIM]` в CFFI
ATM Я работаю на тиражирование следующие структуры
#define DIM 3
typedef double REAL;
struct Object_structure {
int numpoints;
REAL (* vertices)[DIM];
int * rings;
};
typedef struct Object_structure * Object;
Функция я пытаюсь позвонить ожидает аргумент типа Object
.
REAL gjk_distance(
Object obj1, REAL (* tr1)[DIM+1],
Object obj2, REAL (* tr2)[DIM+1],
REAL wpt1[DIM], REAL wpt2[DIM],
struct simplex_point * simplex, int use_seed
);
Я написал следующий класс питона для представления такого объекта /-структуры, но у меня возникают проблемы преобразования его в ожидаемый объект CDATA. (На данный момент я просто рассматривает UnitCube, но в конечном счете, я хочу обобщать, что.)
class Box:
def __init__(self, pos):
self._weakkeydict = weakref.WeakKeyDictionary()
self.numpoints = 8
self.rings = [
8, 12, 16, 20, 24, 28, 32, 36,
3, 1, 4, -1,
0, 2, 5, -1,
1, 3, 6, -1,
2, 0, 7, -1,
7, 5, 0, -1,
4, 6, 1, -1,
5, 7, 2, -1,
6, 4, 3, -1]
x, y, z = pos
self.vertices = [
[x+0, y+0, z+0],
[x+1, y+0, z+0],
[x+1, y+1, z+0],
[x+0, y+1, z+0],
[x+0, y+0, z+1],
[x+1, y+0, z+1],
[x+1, y+1, z+1],
[x+0, y+1, z+1],
]
@property
def cdata(self):
self._weakkeydict.clear()
#ptr_numpoints = ffi.new("int", self.numpoints)
ptr_rings = ffi.new("int[]", self.rings)
vertices = [ffi.new("REAL[3]", v) for v in self.vertices]
ptr_vertices = ffi.new("REAL *[3]", vertices)
ptr_obj = ffi.new("Object", {
'numpoints': self.numpoints,
'rings': ptr_rings,
'vertices': ptr_vertices})
self._weakkeydict[ptr_obj] = (ptr_rings, ptr_vertices, vertices)
return ptr_obj
С выше я получаю IndexError: too many initializers for 'double *[3]' (got 8)
в строке ptr_vertices = ffi.new("REAL *[3]", vertices)
при вызове:
box1 = Box((0,0,0))
box2 = Box((10,0,0))
d = lib.gjk_distance(
[box1.cdata], ffi.NULL,
[box2.cdata], ffi.NULL,
ffi.NULL, ffi.NULL,
ffi.NULL, 0 )
мне кажется, что размеры как-то переключились. Так как это должен быть массив из 8 элементов с 3 элементами элемента. Я надеюсь, что кто-то может указать мне в правильном направлении.
Спасибо. Не могли бы вы прокомментировать, как это относится к 'REAL [] [3]'? – PeterE
Btw, 'ffi.new ('REAL (*) [3]')' здесь не работает, но 'ffi.new (" REAL [] [3] ")' делает. По-видимому, синтаксис CFFI не является синтаксисом Си. То, что должно быть сохранено, представляет собой (в данном случае) 8 на 3 двумерный (вложенный) массив, причем 3 - размер внутреннего/второго измерения. Я понимаю, что вместо определения массива с фиксированным размером 8x3 внешний размер обобщается указателем на первый 3-элементный подмассив, поэтому c-декларация является 'REAL (*) [3]'. В CFFI это, по-видимому, должно быть переведено на 'REAL [] [3]' по причинам, которые я не понимаю. – PeterE
@PeterE проверка обновление. – kennytm