3个版本 (重大变更)
0.4.0 | 2023年7月29日 |
---|---|
0.3.0 | 2023年6月7日 |
0.2.0 | 2022年7月5日 |
1449 在 过程宏 中排名
每月下载 123,103 次
在 33 个 库中使用(直接使用3个)
19KB
428 行
dlopen2
这是对原始的、现在不再维护的 dlopen
的分支,更新了依赖项、修复了错误,并添加了一些新功能。
概览
这个库是我努力使Rust中动态链接库的使用变得简单。之前存在的解决方案要么是不安全的,要么需要编写大量代码来实现简单的事情,从而产生了巨大的开销。我希望这个库能帮助您快速获得所需的内容并避免错误。
快速示例
use dlopen2::wrapper::{Container, WrapperApi};
#[derive(WrapperApi)]
struct Api<'a> {
example_rust_fun: fn(arg: i32) -> u32,
example_c_fun: unsafe extern "C" fn(),
example_reference: &'a mut i32,
// A function or field may not always exist in the library.
example_c_fun_option: Option<unsafe extern "C" fn()>,
example_reference_option: Option<&'a mut i32>,
}
fn main(){
let mut cont: Container<Api> =
unsafe { Container::load("libexample.so") }.expect("Could not open library or load symbols");
cont.example_rust_fun(5);
unsafe{ cont.example_c_fun() };
*cont.example_reference_mut() = 5;
// Optional functions return Some(result) if the function is present or None if absent.
unsafe{ cont.example_c_fun_option() };
// Optional fields are Some(value) if present and None if absent.
if let Some(example_reference) = &mut cont.example_reference_option {
*example_reference = 5;
}
}
功能
主要功能
- 支持大多数平台,且具有平台无关性。
- 与Rust的错误处理机制一致,使得犯错误的可能性大大降低。
- 非常轻量。它主要使用零成本包装器来创建对平台API的安全抽象。
- 线程安全。
- 面向对象编程友好。
- 具有低级API,提供使用库的完全灵活性。
- 具有两个高级API,以各自的方式防止悬挂符号。
- 高级API支持将符号自动加载到结构中。您只需定义一个表示API的结构即可。其余的操作将自动完成,并且只需要最少的代码。
- 自动加载符号有助于您遵循DRY原则。
与其他库的比较
功能 | dlopen2 | libloading | sharedlib |
---|---|---|---|
基本功能 | 是 | 是 | 是 |
多平台 | 是 | 是 | 是 |
悬挂符号预防 | 是 | 是 | 是 |
线程安全 | 是 | 某些平台(如FreeBSD)上dlerror() 的线程安全性可能存在问题 |
不支持SetErrorMode(库可能在Windows上阻塞应用程序) |
将符号加载到结构中 | 是 | 不支持 | 不支持 |
开销 | 最小 | 最小 | 一些开销 |
低级、不安全的API | 是 | 是 | 是 |
面向对象友好 | 是 | 不支持 | 是 |
从程序本身加载 | 是 | 不支持 | 不支持 |
获取地址信息(dladdr) | 是 | 仅限Unix | 不支持 |
安全性
请注意,虽然Rust旨在成为100%安全的语言,但它尚未提供使我能够创建100%安全库的机制,因此我不得不接受99%。此外,动态链接库的性质要求将获取的指针转换为在应用程序端定义的类型。这不可能安全。话虽如此,我仍然认为这个库提供了在Rust中可能的最佳方法和最大的安全性。
使用方法
Cargo.toml
[dependencies]
dlopen2 = "0.6"
文档
许可证
此代码根据MIT许可证授权。
变更日志
致谢
特别感谢Simonas Kazlauskas,他的libloading成为我的项目的基础代码。
依赖项
~280–730KB
~17K SLoC