4个版本
0.1.6 | 2021年12月15日 |
---|---|
0.1.5 | 2021年3月23日 |
#393 in 编程语言
33 每月下载量
在 rust-guile-client-example 中使用
530KB
19K SLoC
目录
简介
rust-guile为Rust语言中的guile提供了绑定。
使用它,你可以在Rust程序中嵌入Scheme解释器,编写在Scheme脚本中可用的Rust函数,并启动一个无需额外努力的完整Scheme repl,允许你调用Rust、C和Scheme函数。
用法
libguile的全部内容被重新导出,但这个库提供了一些提高生活质量的辅助函数和宏,使从零开始使用Scheme变得容易。
使用嵌入Scheme解释器的Rust程序将经历三个阶段
- 在Scheme初始化之前
- 在Scheme初始化之后
- 在Scheme启动之后
在阶段1和阶段2之间,Guile引导过程开始,并设置Scheme中使用的全局结构。
通过调用该库定义的 init_scm()
函数,您可以从阶段1进入阶段2。
在阶段2,Scheme运行时存在,您可以在Rust代码中与之交互。您可以注册函数、修改状态等。
在阶段3,Scheme repl启动并替换正在运行的Rust进程。此时,将不再执行任何Rust代码(尽管之前编译并注册到Scheme运行时的函数仍可调用!)用户将看到一个Guile Scheme repl,并可以尽情地修改。
通过调用 run_scm(argc, argv)
函数,您可以从阶段2进入阶段3。
函数注册
为了让Rust函数在Guile Scheme运行时可用,这个库提供了宏 register_void_function
。您需要给这个宏两个参数:首先是一个 二进制字符串(即 &[u8]),包含您希望该函数在Scheme运行时中显示的名称。其次,是已定义的Rust函数的名称。注意,这并不是一个字符串,只需直接放入实际函数名称。您要注册的函数必须定义为 extern "C"
,否则Scheme不知道如何调用它,并且它必须返回一个 SCM
类型对象(该对象也由这个库导出)。
register_void_function
创建一个不接受任何参数的函数。可以定义带有参数的函数,甚至可变参数,但还没有实现有用的包装器。您可以使用 scm_c_define_gsubr
函数注册自己的函数,该函数是不安全的,需要五个参数。
- 函数名称作为二进制字符串,如之前所述
- 所需参数的数量
- 可选参数的数量
- 一个整数,它将被解释为布尔值:1 = 函数有可变参数,0 = 函数没有可变参数
- 函数标签(类似于宏)
用法简述
- 调用
init_scm()
- 编写您的Rust函数,并使用
register_void_function!()
或scm_c_define_gsubr
注册它们 - 调用
run_scm(argc, argv)
前往月球
示例
以下是一个示例客户端程序,它定义了一个简单的Hello World函数,然后启动了Scheme repl。您可以在Repl中运行定义的Rust函数,方法是键入 (hello-from-rust)
并按回车键。您会看到它将消息打印到Guile repl,并返回0!
use rust_guile::*;
use std::os;
extern "C" fn hello_from_rust() -> SCM {
// an example function demonstrating that Rust functions work in Scheme
println!("Hello from Rust!");
unsafe {
scm_from_int8(0)
}
}
fn main() {
let mut ___args = std::env::args().map(|mut arg| arg.as_mut_ptr() as *mut os::raw::c_char).collect::<Vec<*mut os::raw::c_char>>();
let argc = ___args.len() as os::raw::c_int;
let argv: *mut *mut os::raw::c_char = ___args.as_mut_ptr();
init_scm();
register_void_function!(b"hello-from-rust\0", hello_from_rust);
run_scm(argc, argv);
}
此示例的源代码可在 https://gitlab.com/slondr/rust-guile-client-example 找到,并在crates.io上提供。
注意事项
此库对Guile 3.0有严格的要求。大多数发行版都打包了过时的Guile版本,我不知道他们为什么要这样做。如果您使用Arch,请从AUR安装Guile 3。如果您不是,请查看您的平台是否提供二进制发布版本,或者直接从源代码编译。此库要求在编译时将 libguile-3.0
放入加载路径,否则将失败。
如果您的系统使用libguile的奇怪位置,我知道有很多系统是这样的,只需从源代码重新编译此crate,pkg-config应该可以解决这个问题。如果您的系统不支持pkg-config,则此库不适合您。
最后,此库处于早期阶段,并且正在快速发展。到目前为止,我已经成功地定义了一些有趣的Rust程序并将它们加载到Scheme中,但我还没有用它做任何事情特别重大,所以您的体验可能会有很大差异。话虽如此,所有基本功能都已经具备。
欢迎提交拉取请求。
脚注
注意,此字符串遵循Scheme命名规则,而不是Rust命名规则。这意味着,例如,您可以在函数名称中使用 -
。