是否可以从将引用作为参数的 rust dll 导出函数
Posted
技术标签:
【中文标题】是否可以从将引用作为参数的 rust dll 导出函数【英文标题】:Is it possible to export a function from rust dll which takes a reference as a parameter 【发布时间】:2021-07-04 18:52:53 【问题描述】:我是学习 rust 的新手,我看到 rust 使用通用生命周期在编译时验证引用,这非常好。我没有深入研究如何在 rust 中构建 dll 或共享库,但据我所知,可以从 dll 中导出一个函数(就像在 c++ 中一样)。但是,如果我想导出一个将引用作为参数或返回静态引用以外的引用的函数,这将如何工作? dll和应用程序不在同一个项目中,因此在这种情况下编译器无法检查生命周期,因此这根本不可能,就像在没有实例化的情况下无法在c ++中导出模板化函数一样,但我不知道如何实例化通用生命周期在 rust 中起作用。
为什么要问这个问题? rust 旨在成为一种系统编程语言,共享库在任何系统中都是必需的,那么内置 rust 的系统如何在不经过 c 的情况下提供纯 rust 的 api?
在 c++ 中,这就像在 c 中一样:
struct some_type_c
int i;
float f;
void* p;
;
// vary between windows and unix likes
#define EXPORT some_platform_export
EXPORT void use_some_type_c(some_type_c* s) ++s->i;
struct some_type_cpp
int i;
float f;
void* p;
// may be implemented in a cpp file
EXPORT void use() ++i;
;
【问题讨论】:
我也是个新手,但我猜这必须在一个不安全的块中,因为 rust 无法在编译时验证内存使用/指针生命周期,因为它对呼叫者。因此,尽可能避免这种情况。 【参考方案1】:由于 rust 没有稳定的 ABI,导出的函数需要经过 C ABI 并一路处理原始指针。
在使用 C 语言时,通常的做法是创建更符合人体工程学的函数来包装底层 unsafe FFI (foreign function interface) calls 并具有正确的生命周期注释以表示不同引用之间的关系。
动态加载系统库的 crate 通常由两个 crate 组成,一个带有 -sys
后缀,包含 FFI 绑定,另一个更符合人体工程学的版本(例如,openssl
依赖于 openssl-sys
,包含生成的 C 兼容类型,使用bindgen
)。
导出函数时,将它们转换为原始指针时,引用的生命周期会丢失。
但值得注意的是,所有 rust crate 在编译时都是静态链接的,并且生命周期检查是跨 crate 边界强制执行的。
【讨论】:
以上是关于是否可以从将引用作为参数的 rust dll 导出函数的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring 中从将外键作为长属性引用的 json 创建模型?