[心得] 用 Rust 撰寫 Ruby gem (3)消失

看板Ruby作者時間8年前 (2016/12/01 16:57), 8年前編輯推噓4(400)
留言4則, 3人參與, 最新討論串1/1
在最後一篇中,我們寫一個 matrix 的例子 我們仍然會使用 struct,但在 struct 中會再包 2D vector [Update] 加入釋放記憶體相關程式碼,冏rz 想看程式碼的板友,可到以下 repo https://github.com/cwchentw/libmatrix-rust-demo 首先,用 Rust 撰寫 library 部分程式碼 #[repr(C)] pub struct Matrix { m: Vec<Vec<f64>>, } #[no_mangle] pub extern "C" fn matrix_new(nrow: usize, ncol: usize) -> *mut Matrix { let mut m = Vec::new(); for j in 0..(nrow) { let mut n = Vec::new(); for i in 0..(ncol) { n.push(0.0); } m.push(n); } Box::into_raw(Box::new(Matrix { m: m })) } #[no_mangle] pub extern "C" fn matrix_get_at(matrix: *const Matrix, row: usize, col: usize) -> f64 { unsafe { (*matrix).m[row][col] } } #[no_mangle] pub extern "C" fn matrix_set_at(matrix: *mut Matrix, value: f64, row: usize, col: usize) { unsafe { (*matrix).m[row][col] = value; } } #[no_mangle] pub extern "C" fn matrix_free(matrix: *mut Matrix) { if matrix.is_null() { return } unsafe { Box::from_raw(matrix); } } 雖然,我們沒有真正實作 matrix 的處理,只寫了 getter/setter。 但是,這只是展示使用 2D vector 的程式,就請各位板友包涵 同樣地,加入釋放記憶體相關的程式碼 接著,撰寫相關的 C 程式碼 #include <stdio.h> void* matrix_new(size_t, size_t); double matrix_get_at(void*, size_t, size_t); void matrix_set_at(void*, double, size_t, size_t); void matrix_free(void*); int main() { void* m = matrix_new(3, 3); printf("(1, 1) = %lf\n", matrix_get_at(m, 1, 1)); matrix_set_at(m, 99, 1, 1); printf("(1, 1) = %lf\n", matrix_get_at(m, 1, 1)); matrix_free(m); return 0; } 同樣地,用 void* 接 Rust 的 struct 接著,撰寫相關的 Ruby 程式碼 require 'ffi' require 'objspace' module MyLib extend FFI::Library ffi_lib 'c' ffi_lib 'target/release/libmatrix.so' attach_function :matrix_new, [:int, :int], :pointer attach_function :matrix_get_at, [:pointer, :int, :int], :double attach_function :matrix_set_at, [:pointer, :double, :int, :int], :void attach_function :matrix_free, [:pointer], :void class Matrix def initialize(row, col) @m = MyLib::matrix_new(row, col) ObjectSpace.define_finalizer(self, self.class.finalize) end def self.finalize proc { MyLib::matrix_free @m } end def get_at(row, col) MyLib::matrix_get_at(@m, row, col) end def set_at(value, row, col) MyLib::matrix_set_at(@m, value, row, col) end end end m = MyLib::Matrix.new(3, 3) puts "(1, 1) = #{m.get_at(1, 1)}" m.set_at(99, 1, 1) puts "(1, 1) = #{m.get_at(1, 1)}" 同樣地,稍微包裝函式庫,讓語法更接近 Ruby 的語法 透過以上數個範例,可知 Rust 的確有潛力用在 Rugy gem 的撰寫 不過 Rust 上手難度偏高,板工目前也還在跟 Rust 的編譯器奮戰中 Orz 而且,Rust 的能見度和相關資源仍然較少,也是需要考慮的點 是否要將 Rust 引入自己下一個專案中,就請各位板友自行判斷 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 61.216.1.86 ※ 文章網址: https://www.ptt.cc/bbs/Ruby/M.1480582671.A.755.html

12/01 20:36, , 1F
推!Rust真的很難啊
12/01 20:36, 1F

12/01 22:35, , 2F
猛!
12/01 22:35, 2F
※ 編輯: Neisseria (175.182.114.65), 12/04/2016 15:09:51

01/18 09:49, , 3F
我是不是該來補一篇 用Crystal寫Ruby gem 啦XDDD
01/18 09:49, 3F
Crystal 似乎還在 early stage 如果有分享,歡迎貼在版上 XDD ※ 編輯: Neisseria (175.182.119.20), 01/20/2017 09:36:02

01/20 14:03, , 4F
畢竟crystal比rust年輕啊w
01/20 14:03, 4F
文章代碼(AID): #1OF-OFTL (Ruby)
文章代碼(AID): #1OF-OFTL (Ruby)