Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何修复传递int数组时的分段错误?_Python_Numpy_Segmentation Fault_Rust_Ffi - Fatal编程技术网

Python 如何修复传递int数组时的分段错误?

Python 如何修复传递int数组时的分段错误?,python,numpy,segmentation-fault,rust,ffi,Python,Numpy,Segmentation Fault,Rust,Ffi,我有一个Rust(1.2)库,我想使用Rust的FFI使用Python(3.4)中的函数。我在约塞米蒂的OSX 10.10上 几乎所有my函数都将可变切片引用作为输入: pub fn myfunction<T>(array: &mut [T]) { ... } 这很好:使用python的ctypes模块,我可以使用numpy数组调用ffi\u myfunction(): #!/usr/bin/env python3 import ctypes import numpy a

我有一个Rust(1.2)库,我想使用Rust的FFI使用Python(3.4)中的函数。我在约塞米蒂的OSX 10.10上

几乎所有my函数都将可变切片引用作为输入:

pub fn myfunction<T>(array: &mut [T]) { ... }
这很好:使用python的ctypes模块,我可以使用numpy数组调用
ffi\u myfunction()

#!/usr/bin/env python3

import ctypes
import numpy as np

rustlib = ctypes.CDLL("target/debug/libmylib.dylib")

array = np.arange(5, dtype=np.int8)

rustlib.ffi_myfunction(ctypes.c_void_p(array.ctypes.data), len(array))
我还使用
libc::int16_t
libc::int32_t
libc::int64_t
实现了rust,我可以用
np.int16
np.int32
np.int64
调用它们

我还有第二组要从Python调用的Rust函数。这些函数略有不同,因为它们对向量(而不是切片)采用可变引用:

不幸的是,当从Python调用
ffi\u myotherfunction()
时,我遇到了一个分段错误

经过一些调查,我可以说:

  • 添加
    println!()
    myotherfunction()
    ffi\u myotherfunction()
    中的任意位置执行宏,使函数正常运行。输出与预期一致
  • rust库不适用于所使用的任何整数大小(尝试了8、16、32和64位整数)
  • segfault似乎不是来自
    myotherfunction()
    ,而是来自对
    Vec::from_raw\u parts()
    的调用。例如,我可以从
    ffi\u myotherfunction()
    注释掉对
    myotherfunction()的调用,只留下不安全的块,segfault仍然发生
  • 因此,
    slice::from_raw_parts_mut()
    Vec::from_raw_parts()
    之间似乎存在差异

    但我不明白是什么导致了这个错误。我错过什么了吗?我做错什么了吗?numpy存储数据的方式会有问题吗?或者可能是关于生命的东西,借来的东西,或者其他我不了解的概念


    谢谢大家!

    您只应使用
    Vec::from_raw_parts
    处理已在Rust code中通过Rust的分配器分配的数据。其他任何东西都是不安全的

    我希望Python使用malloc,但Rust使用jemalloc。如果jemalloc被指示释放一个不是由jemalloc分配的地址,我相信它会崩溃。因此,如果一个向量被释放(即,它超出了作用域,它的析构函数被运行),或者如果它需要重新分配(例如,如果你把一个元素推到它上面),你会遇到崩溃


    因此,第一个问题是
    Vec
    正在运行其析构函数;完成后,可以通过调用
    std::mem::forget(to_sort)
    对其进行修改。另一个问题是,任何再分配都会崩溃,这是非常危险的;你已经基本上做到了,你不能安全地可变地访问你的向量,你必须非常小心地对待它。实际上,您应该假设
    Vec
    上的所有内容都会崩溃。如果你想用它做什么,你应该用
    &mut[T]

    所以我应该用
    slice::from_raw_parts_mut()
    而不是
    Vec::from_raw_parts()
    ,是吗?
    #!/usr/bin/env python3
    
    import ctypes
    import numpy as np
    
    rustlib = ctypes.CDLL("target/debug/libmylib.dylib")
    
    array = np.arange(5, dtype=np.int8)
    
    rustlib.ffi_myfunction(ctypes.c_void_p(array.ctypes.data), len(array))
    
    pub fn myotherfunction<T>(array: &mut Vec<T>) { ... }
    
    #[no_mangle]
    pub extern "C" fn ffi_myotherfunction(array_pointer: *const libc::int8_t, n: libc::size_t) {
        assert!(!array_pointer.is_null());
        assert!(n != 0);
        let mut to_sort = unsafe {
            Vec::from_raw_parts(array_pointer as *mut i8, n as usize, n as usize)
        };
        myotherfunction(&mut to_sort);
    }