Long story short, I want to call C code from Rust... I've seen crates like cc and cmake which (to my understanding, which might be wrong) can compile C code for use with the Rust language. Though I am capable of producing a compiled .lib file using the CLion IDE. Now I would like to simply link to said .lib file from Rust and just call the code within, is this possible? I have tried a few things, but they just do not seem to link at all...
project structure:
my_rust_project/
my_c_project/
cmake_build_debug/
...
my_c_project.lib
...
...
a_c_file.h
a_c_file.c
...
src/
main.rs
cargo.roml
build.rs
...
build.rs:
fn main() {
println!("cargo:rustc-link-search=my_c_project/cmake-build-debug/");
println!("cargo:rustc-link-lib=static=my_c_project/cmake-build-debug/my_c_project");
}
main.rs:
#[link(name = "my_c_project/cmake-build-debug/my_c_project", kind = "static")]
extern "C" {
fn hello();
}
fn main() {
unsafe {
//hello(); /* if commented the project compiles... */
}
}
Note how you could comment out any of the two prinln!'s in build.rs as well as the #link directive from main.rs in any combination you could think of (i.e. commenting out #link and leaving the println's, or commenting out one println and leaving the #link, and so on...) and the project will continue to compile, though as soon as you uncomment hello(); from fn main() in main.rs, the project will not compile and produce the following error:
LNK2019: unresolved external symbol hello referenced in function blah blah blah ...
I think there is two possible causes, either the library is not link at all, which seems to be the most logical issue to me, which raises the question: what exactly do the println!'s and #link do in this specific scenarion, they do not cause a panic! or error so they must definitly be doing something right? Whatever it is, it cannot be linking the project.
The other issue I can imagine is that there is in fact proper linking going on-ish? But Rust just doesn't understand where exactly to find the function hello within my_c_project.lib...
For clarity I will provide the contents of my_c_project: a_c_file.h:
#ifndef MY_C_PROJECT_A_C_FILE_H
#define MY_C_PROJECT_A_C_FILE_H
void hello();
#endif //MY_C_PROJECT_A_C_FILE_H
a_c_file.c:
#include "a_c_file.h"
#include <stdio.h>
void hello() {
printf("Hello, World!\n");
}
I really want to stress that I want to stay away from cc and cmake (crates) since I have the .lib file ready to go... The question remains, how to call the C functions from a .lib file from within a Rust program?
Thanks for the help!
newly tried thing... changed build.rs to:
fn main() {
println!("cargo:rustc-link-search=my_c_project/cmake-build-debug/");
println!("cargo:rustc-link-lib=static=my_c_project");
}
changed main.rs to:
extern {
fn hello();
}
fn main {
}
renamed my_c_project.lib to libmy_c_project.lib...
This still produces an error:
LINK : fatal error LNK1181: cannot open input file 'libmy_library.lib'
I guess it does not require a .a file per se as it says .lib in the message above.
I was using the wrong build target in Rust, i.e., the c code was compiled with a different toolchain as the rust project.