Rust 中调用 cdylib crate 函数返回的函数时出现段错误

问题描述 投票:0回答:1

如果我在

fn(&mut Box<fn()>)
箱中有一个
cdylib
,并且它将 Box 的值设置为箱中定义的另一个函数,则在调用结果函数时会出现分段错误。

我有两个箱子来测试这个,

lib
use-lib
use-lib
使用libloading 0.8.6,但没有其他依赖项。

这是我的代码

lib/src/lib.rs

fn dangling() {
    println!("Hello from the returned function");
}

#[no_mangle]
pub extern "Rust" fn loaded_fn(func: &mut Box<fn()>) {
    **func = dangling;
}

这是我在

use-lib/src/main.rs
中的代码(我正在加载DLL,因为我在Windows上,我不知道这是否会影响问题):

use libloading::{Library, Symbol};

fn default() {
    println!("function not modified");
}

fn main() {
    let mut dangling_fn: Box<fn()> = Box::new(default);

    unsafe {
        type LoadedFn = extern "Rust" fn(&mut Box<fn()>);

        let lib = Library::new("./lib.dll").unwrap_or_else(|err| {
            panic!("unable to load library: {}", err);
        });
        println!("loaded lib");
        
        let loaded_fn: Symbol<LoadedFn> = lib.get(b"loaded_fn").unwrap_or_else(|err| {
            panic!("unable to get symbol: {}", err);
        });
        println!("loaded function");

        loaded_fn(&mut dangling_fn);
        println!("called function");
    }

    println!("calling dangling function");
    dangling_fn();
}

这是我得到的输出:

loaded lib
loaded function
called function
calling dangling function
error: process didn't exit successfully: `target\debug\use-lib.exe` (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)

我的诊断是

returned_fn
从未加载到
use_lib
中,但我该如何解决这个问题?

rust dll segmentation-fault rust-cargo dangling-pointer
1个回答
0
投票

lib
超出范围时,库将被 unloaded,因此您的
dangling_fn
确实在
unsafe
块之后悬空。所以你必须把它移出范围:

fn main() {
    let mut dangling_fn: Box<fn()> = Box::new(default);
    let lib;
    unsafe {
        type LoadedFn = extern "Rust" fn(&mut Box<fn()>);

        lib = Library::new("./lib.dll").unwrap_or_else(|err| {
            panic!("unable to load library: {}", err);
        });
        println!("loaded lib");
        
        let loaded_fn: Symbol<LoadedFn> = lib.get(b"loaded_fn").unwrap_or_else(|err| {
            panic!("unable to get symbol: {}", err);
        });
        println!("loaded function");

        loaded_fn(&mut dangling_fn);
        println!("called function");
    }

    println!("calling dangling function");
    dangling_fn();
}
© www.soinside.com 2019 - 2024. All rights reserved.