2017-11-25 15 views
0

はこの質問を見た:今のctypes:Cでmallocを構造体の暴露する配列は、

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

私は解決の私のバージョンを実装しようとしているが、struct Arrlen_aの出力があります私の質問は、Parse.arrをPythonのArrオブジェクトの配列(これはもともとC言語で割り当てられている)に設定する適切な方法は何でしょうか?行番号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

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

これは、このLを置換することによって解決されました機能byrefがここには有効ではありませんので、INE pylink.py

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

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

に属性arrは、POINTER(Arr)として宣言されています。私の実装と重要な違いは、構造配列がどのように宣言されているかということです。 Mineはポインタですが、もう1つはゼロサイズの配列を使用します。詳細はhttps://docs.python.org/3/library/ctypes.html#ctypes.byref

関連する問題