[英]ctypes: exposing array of structs malloc'ed in C
Having looked at this question: 看了这个问题:
ctypes: How do I define an array of a structure as a field of another structure? ctypes:如何将一个结构的数组定义为另一个结构的字段?
now I'm trying to implement my version of the solution, but the output of len_a
in struct Arr
is different from how is it set in C. My question is: what is the proper way to set Parse.arr
as an array of Arr
objects in python (which is originally allocated/set in C)? 现在我正在尝试实现该解决方案的版本,但是struct Arr
中len_a
的输出与len_a
中的设置不同。我的问题是:将Parse.arr
设置为Arr
数组的正确方法是什么? python中的对象(最初是在C中分配/设置的)? There is something obviously incorrect on the line self.arr = cast(byref(self.parse.arr),POINTER(Arr*n)).contents
in pylink.py . 也有一些是上线显然是不正确self.arr = cast(byref(self.parse.arr),POINTER(Arr*n)).contents
在pylink.py。
clink.c 链接
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
struct Arr {
int len_a;
};
struct Parse {
struct Arr* arr;
int len_arr;
};
struct Parse* C_new_domain(void) {
int i = 0;
struct Parse* parse = malloc(sizeof(struct Parse));
parse->arr = malloc(SIZE*sizeof(struct Arr));
for (i=0 ; i<SIZE ; i++) {
parse->arr[i].len_a = i;
}
parse->len_arr = SIZE;
return parse;
}
void C_end_program(struct Parse* parse) {
free(parse->arr);
free(parse);
return;
}
pylink.py pylink.py
import sys
from ctypes import *
_lib = cdll.LoadLibrary('./libclink.so')
class Arr(Structure):
def __init__(self, obj, name=""):
self.obj = obj
_fields_ = [("len_a", c_int)]
class Parse(Structure):
def __init__(self, obj, name=""):
self.obj = obj
_fields_ = [("arr", POINTER(Arr)),
("len_arr", c_int)]
class Domain(object):
domain = POINTER(Parse)
parse = None
arr = None
_lib.C_new_domain.argtype = None
_lib.C_new_domain.restype = POINTER(Parse)
_lib.C_end_program.argtype = POINTER(Parse)
def __init__(self):
self.domain = _lib.C_new_domain()
self.parse = self.domain.contents
n = self.parse.len_arr
self.arr = cast(byref(self.parse.arr),POINTER(Arr*n)).contents
def end(self):
_lib.C_end_program(self.domain)
if __name__ == '__main__':
domain = Domain()
for count, array in enumerate(domain.arr):
print "[Hoping this is %d] --> array[%d].len_a is %d"%(count, count, array.len_a)
domain.end()
Output 输出量
[Hoping this is 0] --> array[0].len_a is 25023216
[Hoping this is 1] --> array[1].len_a is 0
[Hoping this is 2] --> array[2].len_a is 10
[Hoping this is 3] --> array[3].len_a is 32512
[Hoping this is 4] --> array[4].len_a is 14962
[Hoping this is 5] --> array[5].len_a is 0
[Hoping this is 6] --> array[6].len_a is 33
[Hoping this is 7] --> array[7].len_a is 0
[Hoping this is 8] --> array[8].len_a is 10
[Hoping this is 9] --> array[9].len_a is 0
This was solved by replacing this line in pylink.py 这是通过替换pylink.py中的这一行来解决的
self.arr = cast(byref(self.parse.arr), POINTER(Arr*n)).contents
with 与
self.arr = cast(self.parse.arr, POINTER(Arr*n)).contents
The attribute arr
is declared as a POINTER(Arr)
, so function byref
is not valid here. 属性arr
被声明为POINTER(Arr)
,因此功能byref
在这里无效。 An important distinction between my implementation the one linked in the question is how the structure arrays are declared. 我的实现与问题中链接的实现之间的重要区别是如何声明结构数组。 Mine is a pointer, whereas the other uses a zero-sized array. 我的是一个指针,而另一个使用零大小的数组。 For more info see: https://docs.python.org/3/library/ctypes.html#ctypes.byref 有关更多信息,请参见: https : //docs.python.org/3/library/ctypes.html#ctypes.byref
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.