如何在 Rust 中使用编译的 C .so 文件 [英] How to use a compiled C .so file in rust

查看:193
本文介绍了如何在 Rust 中使用编译的 C .so 文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<块引用>

由于一些建议而更新

<小时>

系统: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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆