如何从Rust可执行文件导出符号?

Fre*_*rdt 6 rust

我正在尝试从Rust可执行文件导出符号:

#[allow(non_upper_case_globals)]
#[no_mangle]
pub static exported_symbol: [u8; 1] = *b"\0";

fn main() {
    println!("Hello, world!");
}
Run Code Online (Sandbox Code Playgroud)

exported_symbol 似乎没有由生成的二进制文件导出:

$ cargo build
$ nm ./target/debug/test_export| grep exported_symbol
Run Code Online (Sandbox Code Playgroud)

另一方面,如果我使用相同的源构建库,则会导出符号:

$ rustc --crate-type cdylib src/main.rs
$ nm libmain.so| grep exported_symbol
0000000000016c10 R exported_symbol
Run Code Online (Sandbox Code Playgroud)

我在Linux x86-64上使用Rust 1.18.0.

Fra*_*nis 3

我会在.cargo/config文件中推荐这个而不是上面的:

[build]
rustflags = ["-C", "link-args=-rdynamic"]
Run Code Online (Sandbox Code Playgroud)

-rdynamic更便携。特别是,它可以在 Linux 和 MacOS 上运行。

此外,在当前的 Rust/LLVM 版本中,除非实际使用了符号,否则链接器很可能会删除它。

为了避免这种情况,应该调用引用导出函数的虚拟函数(在任何时间点,例如在函数中main)。

此类函数的示例如下:

[build]
rustflags = ["-C", "link-args=-rdynamic"]
Run Code Online (Sandbox Code Playgroud)

当然,导出的函数应该具有以下#[no_mangle]属性:

pub fn init() {
    let funcs: &[*const extern "C" fn()] = &[
        exported_function_1 as _,
        exported_function_2 as _,
        exported_function_3 as _      
    ];
    std::mem::forget(funcs);
}
Run Code Online (Sandbox Code Playgroud)