audio - static struct with C strings for lv2 plugin -


this question has answer here:

i'm trying learn rust (newbie in low level programming), , want translate tiny lv2 amplifier (audio) plugin "amp.c" (c-code) c rust. got working (here), when host terminates, valgrind says " 64 bytes in 1 blocks lost". think know why happens, don't know how fix it.

before tired of reading, here final question:

how statically allocate struct contains c string?

and here introduction:

why happens (i think): host loads library , calls lv2_descriptor()

const lv2_descriptor* lv2_descriptor() {     return &descriptor; } 

which returns pointer statically allocated struct of type lv2_descriptor,

static const lv2_descriptor descriptor = {     amp_uri,     ... }; 

which defined as

typedef struct _lv2_descriptor {     const char * uri;     ... } lv2_descriptor; 

why statically allocated? in amp.c says:

it best define descriptors statically avoid leaking memory , non-portable shared library constructors , destructors clean properly.

however, translated lv2_descriptor() rust as:

#[no_mangle] pub extern fn lv2_descriptor(index:i32) -> *const lv2descriptor {      let s = "http://example.org/eg-amp_rust";      let cstr = cstring::new(s).unwrap();      let ptr = cstr.as_ptr();      mem::forget(cstr);       let mybox = box::new(lv2descriptor{amp_uri: ptr}, ...);      let bxptr = &*mybox *const lv2descriptor;       mem::forget(mybox);      return  bxptr      } 

so it's not statically allocated , never free it, that's guess why valgrind complains?

how trying solve it? i'm trying same thing in rust c-code does, i.e. statically allocate struct (outside of lv2_descriptor()). goal compatible lv2 library, i.e "...to avoid leaking memory..." etc., says in quote, right? tried like:

static ptr1: *const u8 = (b"example.org/eg-amp_rust\n\0").as_ptr(); static ptr2: *const libc::c_char = ptr1 *const libc::c_char; static desc: lv2descriptor = lv2descriptor{amp_uri: ptr2, ...}; 

but not compile, there error messages like

src/lib.rs:184:26: 184:72 error: trait `core::marker::sync` not implemented type `*const u8` [e0277] src/lib.rs:184 static ptr1: *const u8 = b"http://example.org/eg-amp_rust\n\0".as_ptr();                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/lib.rs:184:26: 184:72 note: `*const u8` cannot shared between threads safely src/lib.rs:184 static ptr1: *const u8 = b"http://example.org/eg-amp_rust\n\0".as_ptr();                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/lib.rs:184:26: 184:72 error: static contains unimplemented expression type [e0019] src/lib.rs:184 static ptr1: *const u8 = b"http://example.org/eg-amp_rust\n\0".as_ptr(); 

specific problem/question:

how statically allocate struct contains c string?

the short answer is, don't now. future rust gain ability.

what can do, statically allocate struct contains null pointers, , set null pointers useful when call function. rust has static mut. requires unsafe code, not threadsafe @ , (to best of knowledge) considered code smell.

right here consider workaround fact there no way turn &[t] *const t in static.

static s: &'static [u8] = b"http://example.org/eg-amp_rust\n\0"; static mut desc: lv2descriptor = lv2descriptor {     amp_uri: 0 *const libc::c_char, // ptr::null() isn't const fn (yet) };  #[no_mangle] pub extern fn lv2_descriptor(index: i32) -> *const lv2descriptor {      let ptr = s.as_ptr() *const libc::c_char;      unsafe {         desc.amp_uri = ptr;         &desc *const lv2descriptor      } } 

Comments