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

sn9*_*n99 4 linker ffi dynamic-linking rust

我的main.rs样子

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

fn main() {
    unsafe {
        hello();
    }
}
Run Code Online (Sandbox Code Playgroud)

并且lib.rs

#[no_mangle]
pub fn hello() {
    println!("Hello, World!");
}
Run Code Online (Sandbox Code Playgroud)

我已经编译lib.rs使用rustc --crate-type=cdylib lib.rs -o lib.so

如何链接lib.sorustc main.rs命令?

She*_*ter 5

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

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

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

库文件

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

主文件

extern "C" {
    fn hello();
}

fn main() {
    unsafe {
        hello();
    }
}
Run Code Online (Sandbox Code Playgroud)

编译并执行:

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

当我在 macOS 上时,我曾经otool证明它确实是动态链接的:

extern "C" {
    fn hello();
}

fn main() {
    unsafe {
        hello();
    }
}
Run Code Online (Sandbox Code Playgroud)

也可以看看:


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

库文件

pub fn hello() {
    println!("Hello, World!");
}
Run Code Online (Sandbox Code Playgroud)

主文件

fn main() {
    lib::hello();
}
Run Code Online (Sandbox Code Playgroud)
$ rustc --crate-type=cdylib lib.rs
$ rustc main.rs -L . -l lib
$ ./main
Hello, World!
Run Code Online (Sandbox Code Playgroud)
$ 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)
Run Code Online (Sandbox Code Playgroud)