如何在锈中使用已编译的C .so文件

问题描述 投票:2回答:1

由于某些建议已更新


系统:macOS 10.14.6

我想在这里问的问题是我如何使用rust调用已编译的.so文件,对不起,我是这一部分的新手。

我有一个非常简单的c文件:

#include "add.h"

int add(int a, int b) {
    return a + b;
}

然后我使用gcc-fPIC -shared -o libadd.so add.c将其编译为.so文件并将其放在lib目录中

然后我在rust的build.rs文件中写了这个:


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");
}

我希望我可以使用此功能,main.rs是:

extern { fn add(a: i32, b: i32) -> i32; }

fn main() {
    let c = unsafe { let d = add(3, 5); d };
    println!("c: {:?}", c);
}

[cargo build可以,但是cargo run有错误:

   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

[其他:我将.so更改为.a并且可以正常运货。

示例代码here

谢谢您的帮助!

c rust shared-libraries
1个回答
0
投票

我遇到了同样的问题。 Cargo似乎可以正确构建您的库,因为您明确地告诉它在哪里寻找文件(使用rustc-link-search)。但是,当您运行它时,Linux并不知道它在哪里。

如果您要在已编译的Rust二进制文件上运行ldd,则会得到类似以下内容:

$ ldd target/debug/hello-from-generated-code-3
        linux-vdso.so.1 (0xabcd)
        libadd.so => not found      <----- ldd can't find your library
        ...

这是因为在LD_LIBRARY_PATH中找不到您的.so文件。您可以通过将库复制到相关文件夹或在运行程序时进行设置来解决此问题。例如,您应该能够说:

LD_LIBRARY_PATH

(或您的.so文件所在的任何其他路径-不一定是LD_LIBRARY_PATH=. cargo run

© www.soinside.com 2019 - 2024. All rights reserved.