如果我在
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
中,但我该如何解决这个问题?
当
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();
}