First, I changed dynamiclib to:
#[derive(Debug)] pub struct Tuple (u32,); #[derive(Debug)] pub struct MyStruct { s1: &'static str, s2: String, t: Tuple, } #[no_mangle] pub extern "C" fn test() -> MyStruct { MyStruct { s1: "hello", s2: "world".to_string(), t: Tuple(47), } }And dynamic to:
#[link(name="dynamiclib")] extern { fn test() -> MyStruct; } fn main() { let retval = unsafe { test() }; println!("Got: {:?}", retval); }And (somewhat surprisingly) it worked as expected. Although you get the following error:
warning: found struct without foreign-function-safe representation annotation in foreign module, consider adding a #[repr(C)] attribute to the type, #[warn(improper_ctypes)] on by defaultAt first I considered appeasing the warning, but if it's a library written in rust and called from rust, shouldn't the default
repr(Rust)be safe/correct?
Next, I decided to try loading and re-loading the shared library using this more complex struct... and I started getting SIGSEGV the second time I attempted to use the library.
I came across libloading (crates.io) which purports to be safer wrapper for working with dyanmic libraries, and if nothing else has much better documentation.
A quick change to dynamic/src/main.rs (devoid of error-checking):
let lib = Library::new("libdynamiclib.dylib").unwrap(); let test: SymbolAnd it works correctly even when re-loading the library. So, I was either using stale symbols, or something else. Still several things that I obviously don't fully understand. Hopefully pouring over Rustonomicon will reveal the secrets to me.MyStruct> = unsafe { lib.get(b"test\0").unwrap() }; println!("Got: {:?}", test());
No comments:
Post a Comment