代码之家  ›  专栏  ›  技术社区  ›  drhagen

属性错误:获取所有权或释放CDATA时是免费的

  •  0
  • drhagen  · 技术社区  · 5 年前

    如果我想拥有一个指针 malloc Ed在C中, docs for the Python cffi package this answer 说要用 ffi.gc 具有 lib.free 作为析构函数。但是,当我这样做的时候,我 AttributeError: free 随时待命 自由库 . 在哪里 自由库 定义?

    from tempfile import TemporaryDirectory
    from weakref import WeakKeyDictionary
    
    from cffi import FFI
    
    common_header = """
    typedef struct {
      int32_t length;
      double* values;
    } my_struct;
    """
    
    # FFI
    ffi = FFI()
    
    ffi.cdef(common_header + """
    int func(my_struct*);
    """)
    ffi.set_source('_temp', common_header + """
    int func(my_struct *input) {
      double* values = malloc(sizeof(double) * 3);
      input->length = 3;
      input->values = values;
      return 0;
    }
    """)
    
    with TemporaryDirectory() as temp_dir:
        lib_path = ffi.compile(tmpdir=temp_dir)
    
        lib = ffi.dlopen(lib_path)
    
        func = lib.func
    
    # Using the library
    my_struct = ffi.new('my_struct*')
    func(my_struct)
    
    # Taking ownership of the malloced member
    global_weakkey = WeakKeyDictionary()
    global_weakkey[my_struct] = ffi.gc(my_struct.values, lib.free)
    # AttributeError: free
    
    1 回复  |  直到 5 年前
        1
  •  0
  •   drhagen    5 年前

    医生不强调这一点,但你需要暴露 free 作为自由党的一部分 cdef 就像在Python端访问它的任何其他函数一样。放 void free(void *ptr); 在呼叫中 ffi.cdef 以及 自由的 功能将通过 lib.free 编译后:

    from tempfile import TemporaryDirectory
    from weakref import WeakKeyDictionary
    
    from cffi import FFI
    
    common_header = """
    typedef struct {
      int32_t length;
      double* values;
    } my_struct;
    """
    
    # FFI
    ffi = FFI()
    
    ffi.cdef(common_header + """
    int func(my_struct*);
    void free(void *ptr); // <-- Key to lib.free working later
    """)
    ffi.set_source('_temp', common_header + """
    int func(my_struct *input) {
      double* values = malloc(sizeof(double) * 3);
      input->length = 3;
      input->values = values;
      return 0;
    }
    """)
    
    with TemporaryDirectory() as temp_dir:
        lib_path = ffi.compile(tmpdir=temp_dir)
    
        lib = ffi.dlopen(lib_path)
    
        func = lib.func
    
    # Using the library
    my_struct = ffi.new('my_struct*')
    func(my_struct)
    
    # Taking ownership of the malloced member
    global_weakkey = WeakKeyDictionary()
    global_weakkey[my_struct] = ffi.gc(my_struct.values, lib.free)