Reputation: 150
I have some C code which I compiled to a .so
file which i want to be called from a Rust program.
// hello.c
void greet() {
printf("Hello, world");
}
so I compiled it to a shared object file and added it to my build.rs and it worked fine
// main.rs
#[link(name = "hello")]
extern "C" {
fn greet();
}
fn main() {
unsafe {
greet();
}
}
The problem is the I have a second function in my C code which accepts a char*
as a parameter so I tried to use libc::c_char
to communicate between C and Rust but whenever my program doesn't compile when I import libc
.
// main.rs
#[link(name = "hello")]
use libc::c_char;
extern "C" {
greet();
}
And I already tried to compile just with import libc
(because I thought that might have been the problem) but it works perfectly so it seems like the program only doesn't compile when I am using my C shared object and importing the libc
crate.
This is the error message
error: linking with `cc` failed: exit code: 1
= note: "cc"
= note: Undefined symbols for architecture x86_64:
"_greet", referenced from:
project::main::h501a37fa09c5db9f in project.2q2eogqn7p5k3u7s.rcgu.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Upvotes: 1
Views: 355
Reputation: 65822
The #[link]
attribute must be just before the extern
block. By inserting a use
between the #[link]
attribute and the extern
block, the #[link]
attribute becomes attached to the use
and has no effect. (There really should be a warning for this...)
Upvotes: 3
Reputation: 169
Works just fine for me, are you sure you compiled a static library that Rust linker can use regardless of what else gets linked into the final executable?
I can only guess that this is whats wrong as you haven't provided how exactly you setup your project, and I'd recommend letting cc
crate handle it for you, and if you really need something it doesn't have, contribute to it, instead of manually compiling C code and trying to link it in.
Example
build.rs
fn main() {
cc::Build::new()
.file("src/hello.c")
.compile("hello");
}
src/hello.c
#include <stdio.h>
void greet() {
printf("Hello, world\n");
}
src/main.rs
use libc::c_char;
#[link(name = "hello")]
extern "C" {
fn greet();
}
fn main() {
unsafe {
greet();
}
}
cli
$ cargo run
Compiling link v0.1.0 (~/Desktop/link)
warning: unused import: `libc::c_char`
--> src/main.rs:4:5
|
4 | use libc::c_char;
| ^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: 1 warning emitted
Finished dev [unoptimized + debuginfo] target(s) in 0.50s
Running `~/.cargo/target/debug/link`
Hello, world
Upvotes: 1