有没有可能编译一个Rust库 crate ,这样用户就看不到源代码,但仍然可以使用库?

如果是,所有的泛型都被提供为"源代码"还是一些IR,或者 rust 从C++模板中实现泛型不同?

推荐答案

每个图书馆 crate 都包含大量元数据,无论是静态链接(.rlib)还是动态链接(.so/.dylib/.dll):

  • 模块 struct
  • 导出了macro_rules个宏
  • 类型和特征定义
  • 常量及其初始值设定项表达式
  • 所有函数的签名
  • 标记为#[inline]或泛型的每个函数的整个主体(默认特征方法被视为泛型超过Self)

所有这些都足以复制一些原始源代码(多少取决于泛型的使用),尽管没有注释或其他空白

虽然元数据是二进制的,而不是JSON,但使用librustc从已编译的 crate 中提取所有导出的函数定义,并且相当容易地打印ASTs.

在future ,可能不会进行任何类型判断,因此元数据将对各种IR进行编码——一种可能是CFG,即"控制流图",它已经在一些地方内部使用.

然而,这仍然会expose 出比Java字节码更多的信息,这将是一种优化,你仍然可以近似原始代码(并且很容易得到编译的东西).

因此,我只能推荐两种 Select :

  1. 公开一个C API;它的优点是作为一种稳定的ABI,但它是非常有限和脆弱的;
  2. 仅使用trait对象(而非泛型)公开Rust API;通过这种方式,你可以保持内存安全,所有的单态函数仍然可以正常工作,但是特征对象(动态调度)不能用泛型表达所有可能的模式:特别是,一般性状方法在性状对象上是不可调用的(C++对于混合templatevirtual应该有相似的限制,而在一个具体的情况下可能有可用的解决方案).

Rust相关问答推荐

将JSON密钥转换为Polars DataFrame

如何格式化传入Rust中mysql crate的Pool::new的字符串

如何循环遍历0..V.len()-1何时v可能为空?

有没有一种惯用的方法来判断VEC中是否存在变体?

`RwLockWriteGuard_,T`不实现T实现的特征

try 创建随机数以常量

循环访问枚举中的不同集合

为什么Option类型try块需要类型注释?

什么时候使用FuturesOrdered?

Rust wasm 中的 Closure::new 和 Closure::wrap 有什么区别

try 从标准输入获取用户名和密码并删除 \r\n

Rust 如何将链表推到前面?

为什么 Rust 的临时值有时有参考性有时没有?

错误:将自定义 proc_macro 与用Rust 的宝贝编写的属性一起使用时,无法在此范围内找到属性

类型判断模式匹配panic

返回引用字符串的future

将一片字节复制到一个大小不匹配的数组中

Rust,使用枚举从 HashMap 获取值

为什么这个闭包没有比 var 长寿?

在 Rust 中组合特征的不同方法是否等效?