为什么使用 libc 会阻止 cargo 正确链接我的程序?
Why does use libc stop cargo from linking my program correctly?
我有一些 C 代码,我编译成一个 .so
文件,我想从 Rust 程序中调用它。
// hello.c
void greet() {
printf("Hello, world");
}
所以我将它编译成一个共享对象文件并将其添加到我的 build.rs 并且它工作正常
// main.rs
#[link(name = "hello")]
extern "C" {
fn greet();
}
fn main() {
unsafe {
greet();
}
}
问题是我的 C 代码中有第二个函数,它接受 char*
作为参数,所以我尝试使用 libc::c_char
在 C 和 Rust 之间进行通信,但是每当我的程序没有' 当我导入 libc
.
时编译
// main.rs
#[link(name = "hello")]
use libc::c_char;
extern "C" {
greet();
}
而且我已经尝试只使用 import libc
进行编译(因为我认为这可能是问题所在)但它运行得很好所以似乎程序只有在我使用我的时才无法编译C 共享对象并导入 libc
crate。
这是错误信息
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)
对我来说工作得很好,你确定你编译了一个 Rust linker 可以使用的静态库,而不管其他什么被 link 编辑到最终的可执行文件中?
我只能猜测这有什么问题,因为你没有提供你是如何设置你的项目的,我建议让 cc
crate 为你处理它,如果你真的需要什么它没有,为它做贡献,而不是手动编译 C 代码并尝试 link 它。
例子
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
#[link]
属性必须在 extern
块之前。通过在 #[link]
属性和 extern
块之间插入 use
,#[link]
属性附加到 use
并且没有任何效果。 (真的应该对此发出警告......)
我有一些 C 代码,我编译成一个 .so
文件,我想从 Rust 程序中调用它。
// hello.c
void greet() {
printf("Hello, world");
}
所以我将它编译成一个共享对象文件并将其添加到我的 build.rs 并且它工作正常
// main.rs
#[link(name = "hello")]
extern "C" {
fn greet();
}
fn main() {
unsafe {
greet();
}
}
问题是我的 C 代码中有第二个函数,它接受 char*
作为参数,所以我尝试使用 libc::c_char
在 C 和 Rust 之间进行通信,但是每当我的程序没有' 当我导入 libc
.
// main.rs
#[link(name = "hello")]
use libc::c_char;
extern "C" {
greet();
}
而且我已经尝试只使用 import libc
进行编译(因为我认为这可能是问题所在)但它运行得很好所以似乎程序只有在我使用我的时才无法编译C 共享对象并导入 libc
crate。
这是错误信息
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)
对我来说工作得很好,你确定你编译了一个 Rust linker 可以使用的静态库,而不管其他什么被 link 编辑到最终的可执行文件中?
我只能猜测这有什么问题,因为你没有提供你是如何设置你的项目的,我建议让 cc
crate 为你处理它,如果你真的需要什么它没有,为它做贡献,而不是手动编译 C 代码并尝试 link 它。
例子
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
#[link]
属性必须在 extern
块之前。通过在 #[link]
属性和 extern
块之间插入 use
,#[link]
属性附加到 use
并且没有任何效果。 (真的应该对此发出警告......)