pub extern "C" fn exec_from_haskell(raw: *const c_char) -> *const c_char {
let source = unsafe { CStr::from_ptr(raw) };
let a = &source.to_str().unwrap();
...
let c_str: Vec<c_char> = answer.chars().map(|x| x as c_char).collect();
let ptr = c_str.as_ptr();
ptr
}здесь вернется указатель на локальную переменную, которая умрет после вызова функции. чтобы выдать наружу указатель на данные, которые менеджит раст, надо разместить их в куче, взять указатель, «утечь» (Box::leak) данные, чтобы их раст не освободил по выходу из скоупа, передать указатель наружу. Чтобы потом освободить память, надо передать указатель обратно в раст, восстановить String (у него есть методы для построения из сырого указателя) и освободить. как-то так