使用 Rust 动态库中的错位 Rust 函数

Use mangled Rust functions from Rust dynamic library

编辑备注

由于 Rust (ver.: 1.42) 仍然没有稳定的 ABI,建议使用 extern(目前相当于 extern "C"(可能会更改将来))否则,可能需要重新编译库。
This article explains how to change the calling convention.


目标是能够在使用该库的板条箱中使用名称混乱的函数(这将允许来自不同 modules/namespaces 且具有相同标识符的函数共存)。

我注意到 Rust(版本:1.42)自动假定导出函数的函数标识符是 not 损坏的。

目前我可以成功 link 它并在函数上使用 #[no_mangle]#[export_name="..."] 时使用它。

我正在使用 stable-x86_64-windows-pc-msvc 工具链。


工作示例

rslib/lib.rs:

#[no_mangle] /* Exports it as "func" */
pub extern fn func() { ... }

app/main.rs:

#[link(name="rslib.dll", kind="dylib")]
extern { fn func(); }

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

编译和运行没有问题。


示例无效

rslib/lib.rs:

pub extern fn func() { ... }

使用相同的 "app/main.rs" 会导致 linking 失败: error LNK2019: unresolved external symbol __imp_func referenced in function _ZN8rust_app4main17h52189e261ef80b93E.

手动解决

我想出的解决方案是手动将 #[link_name="..."] 放在 extern 块中的函数上。这样也可以有使用导入函数的模块。
注意:可以用宏完成!

rslib/lib.rs:

pub mod foo {
    #[export_name="foo_func"] /* Also possible to append some identification for different parameters if desired */
    pub extern fn func() { ... }
}

#[export_name="func"]
pub extern fn func() { ... }

app/main.rs:

mod foo {
    #[link(name="rslib.dll", kind="dylib")]
    extern {
        #[link_name="foo_func"]
        pub fn func();
    }
}

#[link(name="rslib.dll", kind="dylib")]
extern {
    #[link_name="_func"]
    pub fn func();
}

fn main() {
    unsafe {
        func();
        foo::func();
    }
}