我在Python中使用ctypes,我需要将一个指向数组指针的指针传递给一些C函数。 这是结构:
typedef struct {
float x;
float y;
float z;
float radius;
} Sphere;
我可以使用以下原型:
void render(Sphere** spheres);
在Python中,我为Sphere结构声明了一个类,我需要将argtypes设置为render
函数:
lib_render = ctypes.cdll.LoadLibrary('librender.so')
class Sphere(ctypes.Structure):
_fields_ = [('x', ctypes.c_float),
('y', ctypes.c_float),
('z', ctypes.c_float),
('radius', ctypes.c_float)]
render = lib_render.render
render.argtypes = [<cannot find out what needs to be here>]
spheres = numpy.array([Sphere(1, 2.8, 3, 0.5),
Sphere(4.2, 2, 1, 3.2)])
render(spheres)
如何正确传递该数组?
答案 0 :(得分:1)
我不会使用numpy,但是如果没有它,后续工作。我假设您是否传递指针指针,指针列表必须以空值终止。
from ctypes import *
class Sphere(Structure):
_fields_ = [('x', c_float),
('y', c_float),
('z', c_float),
('radius', c_float)]
dll = CDLL('test')
dll.render.argtypes = POINTER(POINTER(Sphere)),
dll.render.restype = None
# Create a couple of objects
a = Sphere(1,2,3,4)
b = Sphere(5,6,7,8)
# build a list of pointers, null-terminated.
c = (POINTER(Sphere) * 3)(pointer(a),pointer(b),None)
dll.render(c)
测试DLL:
#include <stdio.h>
typedef struct Sphere {
float x;
float y;
float z;
float radius;
} Sphere;
__declspec(dllexport) void render(Sphere** spheres)
{
for(;*spheres;++spheres)
printf("%f %f %f %f\n",(*spheres)->x,(*spheres)->y,(*spheres)->z,(*spheres)->radius);
}
输出:
1.000000 2.000000 3.000000 4.000000
5.000000 6.000000 7.000000 8.000000
使用numpy
,使用void render(Sphere* spheres, size_t len)
,这有效。如果可以支持Sphere**
,也许更熟悉numpy的人可以发表评论。
from ctypes import *
import numpy as np
class Sphere(Structure):
_fields_ = [('x', c_float),
('y', c_float),
('z', c_float),
('radius', c_float)]
dll = CDLL('test')
dll.render.argtypes = POINTER(Sphere),c_size_t
dll.render.restype = None
a = Sphere(1,2,3,4)
b = Sphere(5,6,7,8)
# c = (Sphere * 2)(a,b)
# dll.render(c,len(c))
d = np.array([a,b])
dll.render(d.ctypes.data_as(POINTER(Sphere)),len(d))