通过FFI调用Rust函数时发生访问冲突

2024-04-25 09:36:28 发布

您现在位置:Python中文网/ 问答频道 /正文

正如标题所述,当我试图在Python中调用以下Rust代码时,我会遇到访问冲突。在

这是生锈代码:

#![crate_type = "dylib"]

extern crate libc;

use libc::c_char;
use std::ffi::CStr;
use std::str;

#[repr(C)]
pub struct AdditionalDetail {
    swis: String,
    sbl: String,
    school_code: String,
    land_assessed_value: u32,
    deed_book: String,
    deed_page: String,
}

#[no_mangle]
pub extern fn parse_details(l: *const c_char) -> AdditionalDetail{
    let _line = unsafe {
        assert!(!l.is_null());
        CStr::from_ptr(l)
    };
    let line = str::from_utf8(_line.to_bytes()).unwrap();
    let _swis = line[52..58].to_owned();
    let _sbl = line[58..78].to_owned();
    let _school_code = line[371..377].to_owned();
    let _land_assessed_value = line[824..836].parse::<u32>().ok().expect("Couldn't convert to an int");
    let _deed_book = line[814..819].to_owned();
    let _deed_page = line[819..824].to_owned();
    AdditionalDetail{swis: _swis, sbl: _sbl, school_code: _school_code, deed_page: _deed_page,
                     land_assessed_value: _land_assessed_value, deed_book: _deed_book}
}

我用Python代码来命名它:

^{pr2}$

我在Rust代码中添加了println!调用,当它试图创建并返回结构时,访问冲突似乎就发生了。我得到的特定错误消息是Process finished with exit code -1073741819 (0xC0000005)。在

在64位Windows10上,32位Rust和Python会出现这种情况。在


Tags: to代码stringvaluelinecodeletland
1条回答
网友
1楼 · 发布于 2024-04-25 09:36:28

我不确定问题的全部范围,但我知道这个问题不会好:你不能通过外国金融机构返回String。在

一个Rust String在概念上是3个部分:指向内存块的指针、内存的长度以及内存中有多少是有效字符串。在

把它和C字符串比较一下。C字符串只是一个指向内存的指针。你不知道有多少内存,你只能通过遍历每个字节直到得到一个NUL字节才知道有效长度。在

更重要的是,String没有标记为#[repr(C)],因此String结构的实际布局取决于Rust编译器。在

我怀疑发生错误是因为Python看到您返回的是一个c_char_p(我假设是一个char *)。然后它尝试读取一个指针的值,然后移动到下一个指针。它读取的“指针”可能是String的指针长度容量,一旦它读到第二个指针,它就会消失在某个地方。在

相反,您需要找出处理此字符串的其他方法。一些想法:

  1. 操作传入的字符串以在断点处添加NUL字节,然后将指针返回到该大块中。在原始字符串被释放后,您需要小心不要使用任何子字符串。另外,原始字符串现在看起来更短,因为它嵌入了NUL字节。我也不知道Python何时将释放该字符串。在
  2. Return an object,它保存一个CString,并具有返回{}结果的方法。在

{从概念上讲,{对于内存块来说,}是有效的。在

相关问题 更多 >