use std::ffi::{CStr, CString}; use std::os::raw::{c_char, c_int, c_void}; #[link(name = "guile-3.0")] #[allow(dead_code)] extern "C" { fn scm_init_guile(); fn scm_c_define_gsubr( name: *const c_char, req: c_int, opt: c_int, rst: c_int, func: extern "C" fn() -> *mut c_void, ); fn scm_c_eval_string(expr: *const c_char) -> *mut c_void; fn scm_to_locale_string(scm_obj: *mut c_void) -> *const c_char; fn scm_c_write(scm_obj: *mut c_void, port: *mut c_void); fn scm_open_output_string() -> *mut c_void; fn scm_get_output_string(port: *mut c_void) -> *mut c_void; fn scm_is_string(scm_obj: *mut c_void) -> c_int; fn scm_is_number(scm_obj: *mut c_void) -> c_int; fn scm_object_to_string(scm_obj: *mut c_void, printer: *mut c_void) -> *mut c_void; } #[link(name = "guiledefs")] extern "C" { pub static scm_undefined: *mut c_void; } extern "C" fn my_rust_function() -> *mut c_void { println!("Hello from Rust!"); unsafe { scm_undefined } } /// Convert a scm object into a string using Guile-builtins fn string_from_scm(scm_obj: *mut c_void) -> Result { unsafe { if scm_obj.is_null() { return Err(()); } if scm_is_string(scm_obj) != 0 { let res_str = CStr::from_ptr(scm_to_locale_string(scm_obj)) .to_string_lossy() .into_owned(); return Ok(res_str); } else { let port = scm_open_output_string(); if port.is_null() { return Err(()); } let res = scm_object_to_string(scm_obj, scm_undefined); if res.is_null() { return Err(()); } let res_str = CStr::from_ptr(scm_to_locale_string(res)) .to_string_lossy() .into_owned(); return Ok(res_str); } } } pub fn smp_guile_init() {} pub fn testguile() { unsafe { scm_init_guile(); let func_name = CString::new("my-rust-function").unwrap(); scm_c_define_gsubr( func_name.as_ptr(), 0, // required arguments 0, // optional arguments 0, // rest arguments my_rust_function, ); let expr = CString::new("(+ 2 3)").unwrap(); let result = scm_c_eval_string(expr.as_ptr()); println!("{:?}", string_from_scm(result)); let expr = CString::new("(my-rust-function)").unwrap(); let result = scm_c_eval_string(expr.as_ptr()); println!("{:?}", string_from_scm(result)); } }