如何仅使用rustc而非货物链接动态Rust库?

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

我的main.rs看起来像

// #[link(name = "lib")]
extern "C" {
    fn hello();
}

fn main() {
    unsafe {
        hello();
    }
}

lib.rs

#[no_mangle]
pub fn hello() {
    println!("Hello, World!");
}

我用lib.rs编译了rustc --crate-type=cdylib lib.rs -o lib.so

如何将lib.so链接到rustc main.rs命令?

rust linker dynamic-linking ffi
1个回答
3
投票

你需要匹配ABI。使用extern "C"块时,需要使用相同的ABI声明函数。

使用平台的约定命名动态库。在macOS上使用.dylib,在Windows上使用.lib,在Linux上使用.so。如果您不提供rustc选项,-o将自动为您执行此操作。

构建动态库之后,需要将其添加到编译器的链接器选项中。 rustc --help有各种编译器选项的列表。 -L在搜索路径中添加了一个目录,-l链接到特定的库。

礼拜.人生

#[no_mangle]
pub extern "C" fn hello() {
    println!("Hello, World!");
}

卖弄.人生

extern "C" {
    fn hello();
}

fn main() {
    unsafe {
        hello();
    }
}

编译并执行:

$ rustc --crate-type=cdylib lib.rs
$ rustc main.rs -L . -l lib
$ ./main
Hello, World!

当我在macOS上时,我使用otool来表明它确实是动态链接的:

$ otool -L main
main:
    liblib.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1)
    /usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0)

也可以看看:


为了完整性,这里是板条箱的“正常”链接:

礼拜.人生

pub fn hello() {
    println!("Hello, World!");
}

卖弄.人生

fn main() {
    lib::hello();
}
$ rustc --crate-type=rlib lib.rs
$ rustc main.rs --extern lib=liblib.rlib
$ ./main
Hello, World!
$ otool -L main
main:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1)
    /usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0)
© www.soinside.com 2019 - 2024. All rights reserved.