Replies: 2 comments
-
关于 Rust 那边涉及到的 dylib 和 libloading 留了点笔记 https://segmentfault.com/a/1190000040591394 . 现在用 https://github.com/calcit-lang/calcit_std 存放了 std lib 的代码, 目前提供的内容非常少. &call-dylib->str |path |fn
&call-dylib:str->bool |path |fn |a
&call-dylib:str->str |path |fn |a
&call-dylib:str:str->str |path |fn |a |b 那么, 需要增加一个 proc 时, 就在 calcit_std 这个库当中添加, defn read-file! (name)
&call-dylib:str->str
str (or-current-path calcit-dirname) "\"/dylibs/libcalcit_std" $ get-dylib-ext
, "\"read_file" name 其中 然后就是涉及到 CString CStr 跟 Rust 当中 String 和 str 转化的问题了, 另外问题主要在结构化数据和错误处理.. Rust 本身有这些功能, 但是 FFI 不能用, |
Beta Was this translation helpful? Give feedback.
-
新的接口 #116 |
Beta Was this translation helpful? Give feedback.
-
背景
当前 calcit-js 可以编译到 JavaScript 使用 Node.js 生态以及浏览器环境的各种能力, 但是在 Rust runtime 当中直接解释执行的能力非常受限制. Calcit 内置的函数是很少的, 提供比较多的是语法糖, 出于语言核心的简单, 其他文件操作的 API 也只有两个, 在场景中需要用到的时候, 就缺失对应的标准库来完成了.
实现方案
https://doc.rust-lang.org/reference/linkage.html
https://docs.rs/libloading/0.7.0/libloading/
通过生成
--crate-type=dylib, #[crate_type = "dylib"]
的动态库, 然后再加载, 可以把 Rust 代码维护在标准库当中, 这样可以加载过来.为了配合这个功能, 就需要有个
calcit-dirname
的变量插入一个路径, 仪表标注识别模块的路径, 然后提供&call-dyn-proc::str-str->str
这样的方法进行调用. 目前是通过插入一个<pkg>.$meta
的命名空间, 在这其中单独写入了calcit-dirname
信息.以及注意传参类型, 由于 Calcit 是 enum 实现的多态的数据, 在动态调用的库当中预计不能带上 Calcit 类型定义, 所以需要使用
string
i64
之类的基础类型, 中间就需要针对性的类型转化, 因此需要提供很多版本的&call-dyn-proc
, 目前先提供认为会常用的几个(草稿):&call-dyn-proc::str->nil
&call-dyn-proc::str->str
&call-dyn-proc::str-str->nil
&call-dyn-proc::str-str->str
&call-dyn-proc::i64->nil
&call-dyn-proc::i64->i64
&call-dyn-proc::i64-i64->nil
&call-dyn-proc::i64-i64->i64
后续看情况扩展, 可能需要扩展出多态数据的调用方式.
模块在本地安装时, 也需要调用命令进行一次编译, 生成对应的
*.so
文件, 或者*.dylib
.可能的问题
目前对动态链接不熟悉, 首先难处理的就是跨平台问题, 目前没有想好怎么解决.
WebSocket 之类的库是否能用类似办法接入, 还不清楚. 带状态的服务, 处理起来会很麻烦, 目前我在 Rust 还没接触到.
特别是对于 Rust 不够熟悉, 在工具使用上估计会碰到一些新问题, 只能发了之后再记录了.
Beta Was this translation helpful? Give feedback.
All reactions