ITPub博客

首页 > 数据库 > 数据库开发技术 > 在 WSL 中学习 Rust ffi

在 WSL 中学习 Rust ffi

原创 数据库开发技术 作者:Rust语言中文社区 时间:2020-05-01 22:52:08 0 删除 编辑
博主最近从新学习 Rust FFI 的使用,但是手头上没有可用的 Linux 环境(Windows 编译c太麻烦了),于是就尝试着使用 WSL来搭建 Rust 环境和简易的 c 编译环境,并记录下中间遇到的一些坑。感谢 Unsafe Rust 群群友 @框框 对本文的首发赞助!感谢 Rust
深水群 @栗子 的 gcc 指导!

阅读须知

阅读本文,你可以知道:
  • 一些配置 WSL 全局变量的技巧
  • 快速配置 Rust 编译运行环境
  • 简单的 gcc 编译技巧
但是,本文不涉及:
  • 如何安装 WSL?
  • 如何解决 WSL 中文乱码问题?
     顺带一提的是,博主通过 VS Code 使用 WSL,因为 Win 10 已经配置成 UTF-8 编码,所以并没有出现乱码问题
  • Rustup 国内镜像有哪些?
  • cargo 详细使用教程
  • 甚至不会讲 Rust FFI 是什么

WSL Rust 环境搭建

由于 WSL 是新装的,没有 Rust 和 gcc/g++ 环境,因此需要安装:
但是由于在国内访问 Rust 官方网站会很慢,因此设置镜像到 Windows 环境变量中:
然后,使用 WSLENV环境变量将上述变量共享到 WSL 中:
然后重启 WSL 终端,重新执行 Rust 一键脚本。
以下两个项目均来自 《Rust编程之道》一书,源代码仓库在这里

Rust 调用 C/C++

Rust 调用 C/C++ 代码可以使用 cc crate 配合 build.rs 预先编译好 C/C++ 的程序提供给 Rust 调用。
首先,创建一个 binary 项目:
项目目录结构如下:
然后编写 sorting.h 和 sorting.cpp:
然后给 Cargo.toml 的 [build-dependecies] 加上 cc crate 依赖:
接着,我们通过 cc 调用对应平台的c/c++编译器,因为我们这个项目是 WSL,所以和调用我们刚安装的 gcc:
接着,我们在 Rust 主程序中,通过 extern 块引入sorting.cpp中的interop_sort函数,并调用它:
然后执行调用:
我们看到,该函数提示我们 C 中并没有等价于 Rust slice 的类型,原因在于如果我们传递 slice,那么在 C/C++ 中就很容易访问超过数组长度的内存,造成内存不安全问题。但是,我们在 Rust 调用的时候,通过同时传入数组 arr 的长度 arr.len(), 来保证函数不会访问未经授权的内存。不过在实践中,应该划分模块,只允许确认过 内存安全的 safe Rust 功能跨越模块调用。

在 C/C++ 中调用 Rust

接下来我们反过来互操作。项目结构如下:
然后配置 Rust 生成两种库——静态库(staticlib)和c动态库(cdylib):
然后添加我们的 Rust 函数:
当然,为了给 C 调用我们还需要编写一个头文件:
在我们的 main.c 中库并调用:
编写 makefile,先调度cargo 编译出我们需要的 Rust 库(动态或链接),然后再运行:

小结

本文通过给出两个简单的示例来展示 Rust 通过 FFI 功能与 C/C++ 生态进行交互的能力, 并且指出几个在实践过程中容易浪费时间的坑:
  1. WSL的环境变量不生效 -> 使用 WSLENV 变量从 Windows 引入使用。
  2. make share 的时候提示 libcallrust.so 找不到 -> 需要在运行时指定 LD_LIBRARY_PATH 变量,引入我们编译的 libcallrust.so 路径。
  3. make static的时候遇到了pthread_* dy*系列函数未定义问题 -> 通过动态链接系统库来支持运行。

原文链接:http://huangjj27.gitlab.io/about/

原文作者:Rust语言中文社区;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2020-06-11

  • 博文量
    1769
  • 访问量
    718745