大家好,我是张晋涛。
近期 Rust 社区/团队有些变动,所以再一次将 Rust 拉到大多数人眼前。
我最近看到很多小伙伴说的话:
“ Rust 还值得学吗?社区是不是不稳定呀”
“ Rust 和 Go 哪个好?”
“ Rust 还值得学吗?”
这些问题如果有人来问我,那我的回答是:
小孩子才做选择,我都要!
当然,关于 Rust 和 Go 的问题也不算新,比如之前的一条推文:
我在本篇中就来介绍下如何用 Go 调用 Rust。
当然,这篇中我基本上不会去比较 Go 和 Rust 的功能,或者这种方式的性能之类的,Just for Fun
FFI 和 Binding
FFI (Foreign Function Interface) 翻译过来叫做外部函数接口(为了比较简单,下文中都将使用 FFI 指代)。最早来自于 Common Lisp 的规范,这是在 wiki 上写的,我并没有去考证。 不过我所使用过的绝大多数语言中都有 FFI 的概念/术语存在,比如:Python、Ruby, Haskell、Go、Rust、LuaJIT 等。
FFI 的作用简单来说就是允许一种语言去调用另一种语言,有时候我们也会用 Binding 来表示类似的能力。
在不同的语言中会有不同的实现,比如在 Go 中的 cgo , Python 中的 ctypes , Haskell 中的 CAPI (之前还有一个 ccall)等。 我个人感觉 Haskell 中用 FFI 相比其他语言要更简单&方便的多,不过这不是本篇的重点就不展开了。
在本文中,对于 Go 和 Rust 而言,它们的 FFI 需要与 C 语言对象进行通信,而这部分其实是由操作系统根据 API 中的调用约定来完成的。
我们来进入正题。
准备 Rust 示例程序
Rust 的安装和 Cargo 工具的基本使用,这里就不介绍了。大家可以去 Rust 的官网进行了解。
用 Cargo 创建项目
go-rustrustdemo--lib准备 Rust 代码
rustdemoCString::new(str_name).unwrap().into_raw()编译 Rust 代码
Cargo.tomlcrate-type = ["cdylib"]libc然后进行编译
.so准备 Go 代码
Go 环境的安装之类的这里也不再赘述了,继续在我们的 go-rust 目录操作即可。
编写 main.go
import "C"下面的代码很简单,定义了一个字符串,传递给 rustdemo 函数,然后打印 C 处理后的字符串。
lib/rustdemo.h编译代码
rustdemo.solib所以完整的目录结构就是:
编译:
可以看到,第一行的输出是由 Go 传入了 Rust , 第二行中则是从 Rust 再传回 Go 的了。符合我们的预期。
总结
本篇介绍了如何使用 Go 与 Rust 进行结合,介绍了其前置关于 FFI 相关的知识,后续通过一个小的实践演示了其完整过程。 感兴趣的小伙伴可以自行实践下。
欢迎订阅我的文章公众号【MoeLove】