如何动态调用共享库中的函数?
How to dynamically call a function in a shared library?
我有一个 Rust 项目,设置为可执行文件。我正在尝试动态调用一个外部共享库,它也是用 Rust 编写的。我在发布时编译了外部库,我已经尝试了 cdylib
和 dylib
.
这两种板条箱类型
我正在使用 crate libloading,它声称能够动态加载共享库函数,只要它们只使用原始参数。当我尝试使用这个 crate 运行 我的代码时,我不断收到这个错误。
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: GetProcAddress { source: Os { code: 127, kind: Other, message: "The specified procedure could not be found." } }', src\main.rs:14:68
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
main.rs/main():
let now = Instant::now();
unsafe {
let lib = libloading::Library::new(
"externtest.dll").unwrap();
let foo3: Symbol<extern fn(i32) -> i32> = lib.get(b"foo").unwrap();
println!("{}", foo(1));
}
let elapsed = now.elapsed();
println!("Elapsed: {:?}", elapsed);
lib.rs:
pub extern "C" fn foo3(i:i32) -> i32{
i
}
首先,您的库函数名为 "foo3"
,但您正在尝试加载符号 "foo"
。
其次,库函数的符号可能由于重整而与其名称不匹配。您需要告诉编译器不要使用 #[no_mangle]
属性执行此操作:
#[no_mangle]
pub extern "C" fn foo(i: i32) -> i32 {
i
}
第三,这主要是一种风格选择,但我会在定义符号时指定 ABI extern "C"
。尽管 extern
with no epecified ABI uses the "C"
ABI,我发现还是直截了当更好。
use libloading::{Library, Symbol};
fn main() {
unsafe {
let lib = Library::new("externtest.dll").unwrap();
let foo = lib
.get::<Symbol<extern "C" fn(i32) -> i32>>(b"foo")
.unwrap();
println!("{}", foo(1));
}
}
以上应该没有问题。
我有一个 Rust 项目,设置为可执行文件。我正在尝试动态调用一个外部共享库,它也是用 Rust 编写的。我在发布时编译了外部库,我已经尝试了 cdylib
和 dylib
.
我正在使用 crate libloading,它声称能够动态加载共享库函数,只要它们只使用原始参数。当我尝试使用这个 crate 运行 我的代码时,我不断收到这个错误。
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: GetProcAddress { source: Os { code: 127, kind: Other, message: "The specified procedure could not be found." } }', src\main.rs:14:68
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
main.rs/main():
let now = Instant::now();
unsafe {
let lib = libloading::Library::new(
"externtest.dll").unwrap();
let foo3: Symbol<extern fn(i32) -> i32> = lib.get(b"foo").unwrap();
println!("{}", foo(1));
}
let elapsed = now.elapsed();
println!("Elapsed: {:?}", elapsed);
lib.rs:
pub extern "C" fn foo3(i:i32) -> i32{
i
}
首先,您的库函数名为 "foo3"
,但您正在尝试加载符号 "foo"
。
其次,库函数的符号可能由于重整而与其名称不匹配。您需要告诉编译器不要使用 #[no_mangle]
属性执行此操作:
#[no_mangle]
pub extern "C" fn foo(i: i32) -> i32 {
i
}
第三,这主要是一种风格选择,但我会在定义符号时指定 ABI extern "C"
。尽管 extern
with no epecified ABI uses the "C"
ABI,我发现还是直截了当更好。
use libloading::{Library, Symbol};
fn main() {
unsafe {
let lib = Library::new("externtest.dll").unwrap();
let foo = lib
.get::<Symbol<extern "C" fn(i32) -> i32>>(b"foo")
.unwrap();
println!("{}", foo(1));
}
}
以上应该没有问题。