2017-11-25 242 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