7个版本 (4个重大变更)
0.7.0 | 2024年2月6日 |
---|---|
0.6.1 | 2023年7月30日 |
0.5.0 | 2023年6月7日 |
0.4.1 | 2022年7月8日 |
0.3.0 | 2022年7月5日 |
#25 in 操作系统
每月下载量 162,286
用于 524 个crate(23 个直接使用)
84KB
1K SLoC
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支持将符号自动加载到结构中。你只需要定义一个表示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成为我的项目的代码基础。
依赖项
~27–375KB