I've tagged this as "beginner" because, alright I'm experienced in Rust, I'm very inexperienced with C; I know the syntax and I know a lot of concepts about it, but I've never used it properly. I would like to use Rust/C FFI with bindgen, but it's not quite working. Here's a minimal example:
build.rs
use std::env;
use std::path::PathBuf;
fn main() {
println!("cargo:rustc-link-search=./");
let bindings = bindgen::Builder::default()
.header("c_code.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.expect("Unable to generate bindings");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}
src/main.rs
use std::ffi::CStr;
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
fn main() {
unsafe {
let pointer = test_string();
let c_str = CStr::from_ptr(pointer);
println!("{}", c_str.to_str().unwrap());
free_test_string(pointer);
}
}
c_code.h
void write_to_string(char* pointer);
void free_test_string(char* pointer);
char* test_string();
c_code.c
#include <stdlib.h>
void write_to_string(char* pointer) {
pointer = "tset";
}
void free_test_string(char* pointer) {
free(pointer);
}
char* test_string() {
char* test_string = malloc(sizeof(char) * 5);
test_string = "test";
write_to_string(test_string);
return test_string;
}
And when I try to run this, it fails:
$ gcc -shared -o libc_code.so -fPIC c_code.c
> [Success, no output]
$ cargo build
> Compiling c-ffi-testing v0.1.0 (/home/cha14031/playground/c-ffi-testing)
error: linking with `cc` failed: exit status: 1
|
= note: LC_ALL="C" PATH="/home [LONG OUTPUT OMITTED]
= note: /usr/bin/ld: /home/cha14031/playground/c-ffi-testing/target/debug/deps/c_ffi_testing-ac44afdba4a8831e.294zjevdd0plx23d.rcgu.o: in function `c_ffi_testing::main':
/home/cha14031/playground/c-ffi-testing/src/main.rs:7: undefined reference to `test_string'
/usr/bin/ld: /home/cha14031/playground/c-ffi-testing/src/main.rs:10: undefined reference to `free_test_string'
collect2: error: ld returned 1 exit status
= note: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
= note: use the `-l` flag to specify native libraries to link
= note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib)
error: could not compile `c-ffi-testing` (bin "c-ffi-testing") due to 1 previous error
All the docs and guides for bindgen don't include compilation instructions for the C-side, which is really frustrating. I think I'm having issues with the C packaging system, I tried putting the extern keyword in front of the functions I used in Rust, but that didn't help. Thank you in advance for any help!