I have a shared library, written in C, that receives a char **buffer
used to return some string.
When calling it from rust using a debug build, everything works. If rust is compiled in release mode, the pointer is null.
I have the C library, compiled with gcc -o libtest.so -shared -Wall -fpic lib.c
#include <stdio.h>
static char *buffer = "this is a string";
void get_buffer(const char **out) {
printf("Pointer: 0x%x\n", (size_t) out);
*out = buffer;
}
And the rust program:
use std::ffi::CStr;
#[link(name = "test")]
unsafe extern "C" {
fn get_buffer(out: &*mut std::ffi::c_char);
}
fn main() {
let buffer: *mut std::ffi::c_char = std::ptr::null_mut();
unsafe { get_buffer(&buffer); }
println!("buffer: {}", buffer.addr());
let cstr = unsafe { CStr::from_ptr(buffer) };
let str = cstr.to_str().unwrap();
println!("{}", str);
}
Running it gives these results:
root@628a88480eca:/app# LD_LIBRARY_PATH=. cargo run
Pointer: 0x278ff5d0
buffer: 139989080453120
this is a string
root@628a88480eca:/app# LD_LIBRARY_PATH=. cargo run --release
Pointer: 0x8a5d8120
buffer: 0
Segmentation fault
What is going on?