From a4feab38468b728c97d9102de32ece0c84bdf529 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Mon, 6 Mar 2023 03:33:57 +0800 Subject: [PATCH] fix: rust c-style string --- include/utils/assets.h | 3 +- src/assets/src/ffi.rs | 66 ++++++++++++++++++++++++++++++++++++++++++ src/assets/src/lib.rs | 34 ++-------------------- src/cleardns.c | 29 +++++++++++++------ 4 files changed, 91 insertions(+), 41 deletions(-) create mode 100644 src/assets/src/ffi.rs diff --git a/include/utils/assets.h b/include/utils/assets.h index cf75abf..2000b48 100644 --- a/include/utils/assets.h +++ b/include/utils/assets.h @@ -14,7 +14,8 @@ void assets_extract(); // RUST DEMO START -void rust_test(const char *const *ptr); +void rust_test_single(const char *ptr); +void rust_test_multi(const char *const *ptr); // RUST DEMO END diff --git a/src/assets/src/ffi.rs b/src/assets/src/ffi.rs new file mode 100644 index 0000000..746533b --- /dev/null +++ b/src/assets/src/ffi.rs @@ -0,0 +1,66 @@ +use std::ffi::{CStr, CString}; +use std::os::raw::c_char; + +/// Load c-style string from `char *` pointer. +unsafe fn load_c_string(ptr: *const c_char) -> String { + + println!("c-style ptr: {:?}", ptr); + + // let s = CStr::from_ptr(ptr).to_str().unwrap(); + // + // println!("rust cstr ptr: {:?}", s.as_ptr()); + // + // let string = format!("{}", s); + // + // println!("rust string ptr: {:?}", string.as_ptr()); + // + // println!(); + + + let a = CString::from(CStr::from_ptr(ptr)); + println!("rust string ptr: {:?}", a.as_ptr()); + + a.into_string().unwrap() + + // String::from(CStr::from_ptr(ptr).to_str().unwrap()) +} + +/// Load c-style string list from `char **` pointer. +unsafe fn load_c_string_list(ptr: *const *const c_char) -> Vec { + let mut index = 0; + let mut string_list: Vec = vec![]; + while *ptr.offset(index) != std::ptr::null() { // traverse until `NULL` + let s = load_c_string(*ptr.offset(index)); + + // println!("string ptr: `{:?}`", s.as_ptr()); + println!("content: `{}`", s); + + println!(); + + string_list.push(s); + + index += 1; + } + string_list +} + +#[no_mangle] +pub unsafe extern "C" fn rust_test_single(ptr: *const c_char) { + println!("enter rust function"); + + let ret = load_c_string(ptr); + println!("ret: {:?}", ret); + + println!("exit rust function"); +} + + +#[no_mangle] +pub unsafe extern "C" fn rust_test_multi(ptr: *const *const c_char) { + println!("enter rust function"); + + let ret = load_c_string_list(ptr); + println!("ret: {:?}", ret); + + println!("exit rust function"); +} diff --git a/src/assets/src/lib.rs b/src/assets/src/lib.rs index ac11b25..9097f4b 100644 --- a/src/assets/src/lib.rs +++ b/src/assets/src/lib.rs @@ -4,42 +4,14 @@ // // use crate::fetch::Asset; -use std::ffi::{c_char, CStr}; +mod ffi; + +// use std::ffi::{c_char, CStr}; // const TIMEOUT: u64 = 60; // // const ASSETS_DIR: &str = "/cleardns/assets/"; -#[no_mangle] -pub unsafe extern "C" fn rust_test(ptr: *const *const c_char) { - println!("enter rust function"); - - unsafe { - - println!("ptr: {:?}", ptr); - - - let mut index = 0; - while *ptr.offset(index) != std::ptr::null() { - - let p = *ptr.offset(index); - - println!("loop: {:?}", p); - - let s = String::from( - CStr::from_ptr(p).to_str().unwrap() - ); - - println!("content: {}", s); - - index += 1; - } - - - } - - println!("exit rust function"); -} // #[tokio::main] // async fn main() { diff --git a/src/cleardns.c b/src/cleardns.c index 1225691..a2d940d 100644 --- a/src/cleardns.c +++ b/src/cleardns.c @@ -120,22 +120,33 @@ void cleardns() { // cleardns service int main(int argc, char *argv[]) { char **demo = string_list_init(); - string_list_append(&demo, "item 1"); - string_list_append(&demo, "item 2"); - string_list_append(&demo, "item 3"); + string_list_append(&demo, "item 1 afdcafaed"); + string_list_append(&demo, "item 2 fasdfcade"); + string_list_append(&demo, "item 3 fadfa"); + string_list_append(&demo, "item 4"); + string_list_append(&demo, "item 5"); char *tmp = string_list_dump(demo); log_warn("dump -> %s", tmp); string_list_free(demo); - log_info("string list -> %p", demo); - log_info("string list 1 -> %p", demo[0]); - log_info("string list 2 -> %p", demo[1]); - log_info("string list 3 -> %p", demo[2]); - log_info("string list 4 -> %p", demo[3]); + log_info("string list -> %p -> %p", &demo, demo); + log_info("string list 1 -> %p -> %p -> `%s`", &demo[0], demo[0], demo[0]); + log_info("string list 2 -> %p -> %p -> `%s`", &demo[1], demo[1], demo[1]); + log_info("string list 3 -> %p -> %p -> `%s`", &demo[2], demo[2], demo[2]); + log_info("string list 4 -> %p -> %p -> `%s`", &demo[3], demo[3], demo[3]); + log_info("string list 5 -> %p -> %p -> `%s`", &demo[4], demo[4], demo[4]); + log_info("string list 6 -> %p -> %p -> `%s`", &demo[5], demo[5], demo[5]); + +// rust_test_single(demo[0]); +// rust_test_single(demo[1]); +// rust_test_single(demo[2]); +// rust_test_single(demo[3]); +// rust_test_single(demo[4]); +// + rust_test_multi(demo); - rust_test(demo); log_warn("test end"); exit(0);