如何在 Rust 中使用编译的 C .so 文件 [英] How to use a compiled C .so file in rust
问题描述
由于一些建议而更新
<小时>
系统:macOS 10.14.6
这里我想问的问题是如何使用rust调用编译后的.so文件,抱歉,我是这部分的新手.
我有一个非常简单的 c 文件:
#include "add.h"int add(int a, int b) {返回 a + b;}
然后我用gcc-fPIC -shared -o libadd.so add.c
编译成.so文件放到lib目录下
然后我在 rust 的 build.rs 文件中写了这个:
<预><代码>使用 std::env;使用 std::path::{Path};fn 主(){让 pwd_dir = env::var("CARGO_MANIFEST_DIR").unwrap();let path = Path::new(&*pwd_dir).join("lib");println!("货物:rustc-link-search=native={}", path.to_str().unwrap());println!("货物:rustc-link-lib=dylib=add");//println!("cargo:rustc-link-lib=static=add");//println!("cargo:rerun-if-changed=src/hello.c");}我希望我能得到并使用这个函数,main.rs 是:
extern { fn add(a: i32, b: i32) ->i32;}fn 主(){让 c = 不安全 { 让 d = 添加 (3, 5);d };println!("c: {:?}", c);}
cargo build
没问题,但是 cargo run
有错误:
编译 hello-from-generated-code-3 v0.1.0 (/Users/niexiaotao/work/rust-server/rust-ffi/hello-from-generated-code-3)在 0.34 秒内完成开发 [未优化 + 调试信息] 目标运行 `target/debug/hello-from-generated-code-3`dyld:库未加载:libadd.so引用自:/Users/niexiaotao/work/rust-server/rust-ffi/hello-from-generated-code-3/target/debug/hello-from-generated-code-3原因:找不到图片[1] 81811 中止货物运行
另一件事:我将 .so 更改为 .a 并且货物运行没问题.
示例代码这里一个>
感谢您的帮助!
我遇到了同样的问题.Cargo 似乎可以正确构建您的库,因为您明确告诉它在哪里查找文件(使用 rustc-link-search
).然而,当你去运行它时,Linux 不知道它在哪里.
如果你在你编译的 Rust 二进制文件上运行 ldd
,你会得到这样的结果:
$ ldd target/debug/hello-from-generated-code-3linux-vdso.so.1 (0xabcd)libadd.so =>未找到 <----- ldd 找不到您的库...
这是因为在 LD_LIBRARY_PATH
.您可以通过将库复制到相关文件夹或在运行程序时设置它来解决此问题.例如,您应该能够说:
LD_LIBRARY_PATH=.货物运行
(或您的 .so 文件所在的任何其他路径 - 不一定 .
)
has updated because of some suggestions
System:macOS 10.14.6
The question I want to ask here is how do I use rust to call a compiled .so file, sorry, I am new to this part.
I have a very simple c file:
#include "add.h"
int add(int a, int b) {
return a + b;
}
Then I used gcc-fPIC -shared -o libadd.so add.c
to compile it into a .so file and put it in the lib directory
Then I wrote this in rust's build.rs file:
use std::env;
use std::path::{Path};
fn main() {
let pwd_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let path = Path::new(&*pwd_dir).join("lib");
println!("cargo:rustc-link-search=native={}", path.to_str().unwrap());
println!("cargo:rustc-link-lib=dylib=add");
// println!("cargo:rustc-link-lib=static=add");
// println!("cargo:rerun-if-changed=src/hello.c");
}
I expect I can get and use this function, main.rs is:
extern { fn add(a: i32, b: i32) -> i32; }
fn main() {
let c = unsafe { let d = add(3, 5); d };
println!("c: {:?}", c);
}
cargo build
is ok, but cargo run
with error:
Compiling hello-from-generated-code-3 v0.1.0 (/Users/niexiaotao/work/rust-server/rust-ffi/hello-from-generated-code-3)
Finished dev [unoptimized + debuginfo] target(s) in 0.34s
Running `target/debug/hello-from-generated-code-3`
dyld: Library not loaded: libadd.so
Referenced from: /Users/niexiaotao/work/rust-server/rust-ffi/hello-from-generated-code-3/target/debug/hello-from-generated-code-3
Reason: image not found
[1] 81811 abort cargo run
other thing: I change the .so to .a and cargo run is ok.
Sample code here
Thank you for your help!
I ran into the same problem. It seems that Cargo can properly build your library because you're explicitly telling it where to look for the file (using rustc-link-search
). However, when you go to run it, Linux doesn't know where it is.
If you were to run ldd
on your compiled Rust binary, you'd get something like this:
$ ldd target/debug/hello-from-generated-code-3
linux-vdso.so.1 (0xabcd)
libadd.so => not found <----- ldd can't find your library
...
This is because your .so file isn't found in LD_LIBRARY_PATH
. You can fix this either by copying your library into a relevant folder or just setting it when you run your program. For example, you should be able to say:
LD_LIBRARY_PATH=. cargo run
(Or any other path where your .so file is - not necessarily .
)
这篇关于如何在 Rust 中使用编译的 C .so 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!