我不知道如何将C库链接到Rust.以下是我所做的:

我的lib.rs文件包含

#[link(name = "test")]
extern {

该图书馆已建成,名称为libtest.a.

我不知道该把它放在哪里.我试过好几个地方,但我在做cargo run次时仍然有这种错误

error: linking with `cc` failed: exit code: 1
//..
note: /usr/bin/ld: no se puede encontrar -ltest
note: /usr/bin/ld: no se puede encontrar -ltest
note: /usr/bin/ld:.......
//..

Translation of the above /usr/bin/ld: no se puede encontrar -ltest -> usr/bin/ld: cannot find -ltest

我不知道该把libtest.a放在哪里,这样/usr/bin/ld才能找到它.Cargo没有告诉我项目中图书馆应该在哪里.

我的Cargo.toml包含

[dependencies.test]
path = "./src/test"

[dependencies]
bitflags = "0.7"
libc = "0.2"

[build-dependencies]
make-cmd = "0.1"

在再次阅读the FFI section of the documentation之后,我认为以前的错误消息可能是因为我正在寻找一个共享库,所以我做了以下更改:

#[link(name = "test", kind = "static")]

在这些更改之后,我仍然不知道如何指示库的位置,但消息现在告诉我:

error: could not find native static library `test`, perhaps an -L flag is missing?

推荐答案

我应该在哪里放置静态库

你想go 哪里就go 哪里.你必须告诉编译器在哪里可以找到它.


首先,让我们创建一个静态库

$ cat hello.c
int square(int value) {
  return value * value;
}
$ gcc -c -o hello.o hello.c
$ ar rcs libhello.a hello.o

接下来,我们使用build script将值设置为rustc-link-search,以指向我放置库的目录:

fn main() {
    println!("cargo:rustc-link-search=/Projects/stack-overflow/using-c-static/");
}

我们现在可以使用库中的函数:

#[link(name = "hello")]
extern "C" {
    fn square(val: i32) -> i32;
}

fn main() {
    let r = unsafe { square(3) };
    println!("3 squared is {}", r);
}

这就是基本功能.您还可以使用构建脚本来指定要链接的库,而不是将其包含在代码中(rustc-link-lib).我更喜欢这样,因为这两种配置是紧挨着的.

您可能还应该遵循*-sys naming convention,创建一个专用于公开底层API的 crate .重要的是,该 crate 应指定link manifest key,以避免链接时出现重复符号.

如果构建脚本需要更多信息,cargo会通过environment variables传递许多参数.

如果你正在编译C代码作为你的 crate 的一部分,你应该查看像cccmake这样的 crate ,这使得构建一个软件变得更加容易.

Rust相关问答推荐

为什么导入Borrow将借入的呼叫改为Borrow::borrow而不是RefCell::borrow

泛型属性比较

如何使用Match比较 struct 中的值

同时从不同线程调用DLL的不同函数会出现分段错误或产生STATUS_STACK_BUFFER_OVERRUN

我如何制作一个变异迭代器来锁定内部数据直到删除?

如果死 struct 实现了/派生了一些特征,为什么Rust会停止检测它们?

在Rust 中移动原始指针的靶子安全吗

Rust Option 的空显式泛型参数

将泛型中的 Box 转换为 rust 中的 Box

Google chrome 和 Apple M1 中的计算着色器

在Rust中实现Trie数据 struct 的更好方式

如何获取模块树?

如何判断服务器是否正确接收数据

Rust/Serde/HTTP:序列化`Option`

Rust 将特性传递给依赖项

Rust 异步和 AsRef 未被发送

有没有办法阻止 rust-analyzer 使非活动代码变暗?

覆盖类型的要求到底是什么?为什么单个元素元组满足它?

相互调用的递归异步函数:检测到循环

基于名称是否存在的条件编译