Ruby string to rust and back again
我正在尝试将 Ruby 中的字符串传递给 rust 可执行文件,对其进行操作并将被操作的字符串传回。
到目前为止,我可以将字符串传入并返回,但我不知道如何将其转换为 rust 字符串,对其进行操作,然后将其传递回 ruby??。这是我到目前为止所拥有的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | // lib.rs use std::ffi::CStr; #[no_mangle] pub extern fn return_string(test_str: &CStr) -> &CStr { // working funciton test_str } #[no_mangle] pub extern fn manipulate_and_return_string(mystr: &CStr) -> &CStr { // mystr type == &std::ffi::c_str::CStr // println!("{:?}", mystr); => std::ffi::c_str::CStr` cannot be formatted using `:?` let cstr = mystr.to_bytes_with_nul(); // println!("{:?}", mystr); => [] // cstr type == &[u8] let ptr = cstr.as_ptr(); // ptr type == *const u8 // println!("{:?}", mystr); => 0x7fd898edb520 let str_slice: &str = std::str::from_utf8(cstr).unwrap(); // str type == &str // println!("{:?}", mystr); =>"" let str_buf: String = str_slice.to_owned(); // str_bug == collections::string::String // println!("{:?}", mystr); =>"" } |
1 2 3 4 5 6 7 8 9 10 | # rust.rb require 'ffi' module Rust extend FFI::Library ffi_lib './bin/libembed.dylib' attach_function :return_string, [:string], :string attach_function :manipulate_and_return_string, [:string], :string end |
感谢 Steve Klabnik、shepmaster 和 DK 的一些指导,我想出了如何在 Rust 中编写外部字符串 concat 函数并在 Ruby 中使用它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | // lib.rs #![feature(libc)] #![feature(cstr_to_str)] #![feature(cstr_memory)] extern crate libc; use std::ffi::{CStr,CString}; #[no_mangle] pub extern fn concat(s1: *const libc::c_char, s2: *const libc::c_char) -> *const libc::c_char { let s1_cstr = unsafe { CStr::from_ptr(s1) }; // &std::ffi::c_str::CStr let s2_cstr = unsafe { CStr::from_ptr(s2) }; // &std::ffi::c_str::CStr let s1_and_str = s1_cstr.to_str().unwrap(); // &str let s2_and_str = s2_cstr.to_str().unwrap(); // &str let mut s1_string = s1_and_str.to_string(); // collections::string::String s1_string.push_str(s2_and_str); // s1_string + s2_and_str); // same thing let concated_string = CString::new(s1_string).unwrap(); // std::ffi::c_str::CString concated_string.into_ptr() // const i8 } |
1 2 3 4 5 6 7 8 9 | # rust.rb require 'ffi' module Rust extend FFI::Library ffi_lib './bin/libembed.dylib' attach_function :concat, [:string, :string], :string end |
1 2 3 | #calling the function in Ruby Rust.concat('This is a ', 'cohesive sentence') # => 'This is a cohesive sentence' |