gpt4 book ai didi

rust - 手动调用一个rust动态库

转载 作者:行者123 更新时间:2023-11-29 07:43:08 25 4
gpt4 key购买 nike

我目前正在研究 DynamicLibrary .

我的动态库代码(使用rustc --crate-type dylib dylib.rs编译):

// dylib.rs
#[no_mangle]
pub fn minicall() -> u8 {
3u8
}

调用它的代码:

// caller.rs
use std::dynamic_lib::DynamicLibrary;

fn main() {
let mut v = Vec::new();

DynamicLibrary::prepend_search_path(&::std::os::getcwd());

match DynamicLibrary::open(Some("./libdylib.so")) {
Err(e) => panic!("ERROR: {}", e),
Ok(lib) => {
println!("Unsafe bloc !");
let func = unsafe {
match lib.symbol::< fn() -> u8 >("minicall") {
Err(e) => { panic!("ERROR: {}", e) },
Ok(f) => { *f },
}
};
println!("call func !");
let new_value = func();

println!("extend vec !");
v.push(new_value);
}
}

println!("v is: {}", v);
}

我有这个输出:

~> ./caller 
Unsafe bloc !
call func !
Illegal instruction

在这里我完全迷路了。我做错了什么?

最佳答案

这里的问题是如何symbol功能有效。它有签名:

unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String>

加载的库基本上是内存中的一个大数组,其中某些地址标有名称(符号名称)。查询符号查找地址并直接返回指向它的指针。库中的函数是一长串指令,因此查询函数名称会返回一个直接指向开始的(函数)指针。然后可以将其作为普通函数指针调用。 rust DynamicLibrary API返回此指针,即*mut T直接指向动态库中的内存块(假设/希望是 T 类型)。

类型fn(...) -> ...本身就是一个函数指针,也就是说,它是8个字节(或4个字节)存储它所代表的函数的开始地址。因此,调用 lib.symbol::< fn() -> u8 >("minicall")是说“给我找到一个叫做 minicall 的东西的地址(它是一个函数指针)”,它并不是说“给我找到一个叫做 minicall 的东西的地址(它是一个函数指针)”是一个函数)”。 *mut (fn() -> u8) 的返回值然后是双重间接的,并且取消引用它以调用它是将函数代码的前 8(或 4)个字节解释为指针(即随机机器指令/函数前奏),而不是执行它们。

(旁注:如果您的图书馆中有 #[no_mangle] pub static minicall: fn() -> u8 = the_real_minicall;,它可能会起作用,但您可能不想要它。)

调用lib.symbol::<T>("minicall")正在返回我们想要的确切函数指针(也就是说,它返回一个指向 minicall 代码开头的指针),所以它只是向编译器表达这个问题。不幸的是,目前没有类型 T这使得 *mut T一个函数指针,所以必须先设置 T = u8 (即 lib.symbol::<u8>("minicall") ),然后通过 transmute::<_, fn() -> u8>(pointer) 将返回值转换为适当的函数指针类型.

(即使在其他答案被接受后我也在回答这个问题,因为我认为它没有很好地解释原因,只是给出了解决方案。)


最后一件事,在这种情况下这不是问题,但它经常使人绊倒:Rust ABI(用于 fn(...) -> ... 类型函数的调用约定)与 C ABI 不同,因此函数从 C 动态库加载的类型应为 extern "C" fn(...) -> ... , 不是 fn(...) -> ... .

关于rust - 手动调用一个rust动态库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26688575/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com