fn main() {
let str1: &str = "First";
let str2: &str = "Second";
let s: &str = unsafe { concat(str1, str2) };
println!("Result: {}", s);
}
What about freeing memory, what happen for the result will it remain in the memory, or free/dropped automatically upon exiting the unsafe block, or shall I do any thing for it?
Get rid of all the 'statics. The return value simply can't be 'static (you're creating it at runtime, after all), and there's no reason to restrict either argument to only 'static strings.
I think that's correct.
The only "automatic" deallocating that happens in Rust is through implementations of the Drop trait. &str is a non-owning type, so it cannot and does not have a (non-trivial, deallocating) Drop implementation. Plus, memory must be freed by the same allocator that allocated it, so you need to go back into C to use C's free(). I believe what people typically do here is write a Rust wrapper type with a Drop impl which makes that call into C.
Note that the unsafe keyword has no effect on any of these semantics. All it does here is permit calling an unsafe/extern function. Variables declared inside a block get dropped at the end of a block, whether it's {} or unsafe {} or if {} or whatever kind of block. Your snippet only declares variables outside the unsafe {} block.
You probably want to convert the result of concat() back into a &CStr that you can more easily use in Rust, rather than leaving it as a raw pointer. The CStr:: from_ptr method is intended for that, but you need to ensure the C code is passing a valid pointer (which it appears to in this case).
@RustyYato suggested a Deref implementation for the Concat type, which would wrap the call to from_ptr, and create a safe abstraction to manage the underlying pointer.
Thanks a lot, not back for freeing memory issue, as I got error at:
impl Drop for Concat {
fn drop(&mut self) {
unsafe { c_free_string(self.0) }
}
}
Which is:
error LNK2019: unresolved external symbol c_free_string referenced in function ZN62$LT$rust_webview..Concat$u20$as$u20$core..ops..
drop..Drop$GT$4drop17h012a6d16b98af5e1E
This is because you haven't written c_free_string function. C doesn't have automatic memory management, so every string that C returns is going to be leaked memory, unless you manually make a function to free that memory, and ensure that function is invoked.
If you can guarantee that concat used malloc to make that string, then in Rust you can use libc::free instead.
Whoops, I forgot the signature of Debug::fmt, the second error shows exactly the problem. You need to change the signature to fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result