2017-11-25 245 views
0

说完看着这样一个问题:ctypes的:用C malloc分配结构的暴露阵列

ctypes: How do I define an array of a structure as a field of another structure?

现在我想实现我的版本的解决方案,但在len_astruct Arr输出不同于它在C中的设置。我的问题是:什么是将Parse.arr设置为python中的一个Arr对象数组的正确方法是什么?(最初是在C中分配/设置的)?在线self.arr = cast(byref(self.parse.arr),POINTER(Arr*n)).contentspylink.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

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() 

输出

[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 

回答

0

这是通过更换这个升解决国家统计局在pylink.py

self.arr = cast(byref(self.parse.arr), POINTER(Arr*n)).contents 

self.arr = cast(self.parse.arr, POINTER(Arr*n)).contents 

属性arr声明为POINTER(Arr),所以功能byref无效这里。我的实现之间的一个重要区别就是如何声明结构数组。我是一个指针,而另一个使用零大小的数组。详情请参阅:https://docs.python.org/3/library/ctypes.html#ctypes.byref