Rustler 項目還不是很成熟, 基本可用. 有興趣的能夠給做者提 Issue.git
Rustler 是一個在安全的用 Rust 編寫 Erlang NIF 的庫. 這裏安全的含義是, 它不會致使 BEAM(Erlang 虛擬機)的崩潰. 該庫提供了一個設施用於生成與BEAM交互的模板, 處理Erlang Term的編碼和解碼. Rustler 適用於 Erlang 和 Elixir, Elixir 是首選的.github
安全性 - 用 Rust 編寫的NIF毫不會致使BEAM崩潰.安全
互操做性 - 編碼和解碼Rust值到Erlang Term就像調用函數同樣容易.app
複合類型 - 能夠用屬性指定某個 Rust 結構爲 Encodable, Decodableide
資源對象 - 能夠安全地傳遞Rust結構到Erlang代碼, 該結構再也不被引用時自動刪除.函數
最簡單的入門方法是, 使用Mix項目生成器工具
運行下面的命令安裝Rustler的Mix項目生成器ui
mix archive.install https://github.com/hansihe/rustler_archives/raw/master/rustler_installer.ez
運行下面的命令建立一個rustler項目編碼
mix rustler.new
須要安裝 Nightly 版本的 Rust. 首先安裝 rustup. 並在項目目錄下執行 rustup override add nightly-2016-05-07-x86_64-apple-darwin
.spa
下面是一個最小的Rust NIF實現, 它只是簡單的實現了一個加法函數返回兩個數字的和.
#![feature(plugin)] #![plugin(rustler_codegen)] #![feature(link_args)] #[link_args = "-flat_namespace -undefined suppress"] extern {} #[macro_use] extern crate rustler; use rustler::{ NifEnv, NifTerm, NifResult, NifEncoder }; rustler_export_nifs!( "Elixir.Test", [("add", 2, add)], None ); fn add<'a>(env: &'a NifEnv, args: &Vec<NifTerm>) -> NifResult<NifTerm<'a>> { let num1: i64 = try!(args[0].decode()); let num2: i64 = try!(args[1].decode()); Ok((num1 + num2).encode(env)) }
OSX下面的編譯問題參考 https://github.com/hansihe/Ru...
對於使用Mix的項目, 在Hex上有一個助手包. 這個包包含一個Mix編譯器, 進行自動環境檢查, crate 編譯和nif加載. 若是使用mix,極其推薦使用這個包, 它使你基於Rust開發Erlang NIF更加方便.
要啓動用Rust NIF的自動編譯, 完成以下步驟:
添加 rustler 到 mix.exs 依賴
添加 :rustler 編譯器到項目的 compilers
列表. compilers: [:rustler] ++ Mix.compilers
添加一個 rustler_crates: ["CRATE_PATH"]
到 project
函數, CRATE_PATH
應該是一個到包含 Cargo.toml
文件的相對於mix項目更目錄的相對路徑.
完成後 mix.exs
文件看起來像這樣:
defmodule YourProject.Mixfile do use Mix.Project def project do [app: :your_project, [...] compilers: [:rustler] ++ Mix.compilers, rustler_crates: ["."], deps: deps] end [...] defp deps do [{:rustler, "~> 0.0.7"}] end end
而後能夠經過 mix compile
編譯項目, 若是環境設置有任何問題, rustler編譯器插件應該可以提示相關的說明如何解決.
加載一個Rust NIF和普通的NIF沒什麼區別. 實際的加載是經過調用 Rustler.load_nif(<LIBRARY_NAME>)
完成的, 一般在Elixir用@on_load
鉤子來實現.
defmodule MyProject.NativeModule do @on_load :load_nif defp load_nif do :ok = Rustler.load_nif("<LIBRARY_NAME>") end // When loading a NIF module, dummy clauses for all NIF functions are required. // NIF dummies usually just error out when called when the NIF is not loaded, as that should // never normally happen. def my_native_function(_arg1, _arg2), do: exit(:nif_not_loaded) end
注意 <LIBRARY_NAME>
是Cargo.toml
文件中[lib]
中的庫名字.
打開 Rustler
的 Cargo.toml
文件咱們看到下面的代碼
[dependencies] ruster_unsafe = ">=0.4" libc = ">=0.1" lazy_static = "0.1.*"
它依賴 ruster_unsafe
了去實現用 Rust 開發 NIF, ruster_unsafe
是一個底層的Erlang NIF的語言綁定, Rustler 只是一個集成到 Elixir 的助手工具.