为什么使用libc阻止货物正确链接我的程序?

问题描述

我有一些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时程序未编译时, / p>

//main.rs

#[link(name = "hello")]
use libc::c_char;
extern "C" {
    greet();
}
...

而且我已经尝试仅使用import libc进行编译(因为我认为可能是问题所在),但是它运行良好,因此似乎仅当我使用c共享库并导入libc板条箱。

这是错误消息

>>> cargo build

...

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)
          

error: aborting due to previous error; 1 warning emitted

我是生锈的新手,我不太了解货物的工作原理,因此,请多谢帮助。

解决方法

#[link]属性必须位于extern块之前。通过在use属性和#[link]块之间插入extern#[link]属性将附加到use,并且无效。 (对此确实应该有警告...)

,

对我来说工作很好,您确定您编译了一个Rust链接器可以使用的静态库,而不管最终可执行文件中有什么链接吗?

我只能猜测这是问题所在,因为您还没有提供设置项目的准确方式,因此我建议让cc板条箱为您处理,如果您确实需要它,不必为它贡献力量,而不必手动编译C代码并尝试将其链接。


示例

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...