如何从Rust动态库调用名字被混淆的函数?
在Rust 1.42版本里(稳定ABI还未正式支持),跨crate调用函数时有个关键实践要点:推荐使用extern(当前等价于extern "C",未来版本可能会有变更),否则你的库可能需要重新编译才能保证兼容性。接下来我会说明如何调整调用约定,让使用该库的crate能够调用名字被混淆的函数(这一特性可以让不同模块/命名空间中的同名标识符函数共存)。
我测试后发现,Rust 1.42会自动假设导出函数的标识符未被混淆。目前只有在函数上使用#[no_mangle]或#[export_name="..."]属性时,才能成功完成链接和调用。我使用的工具链是stable-x86_64-windows-pc-msvc。
可正常运行的示例
库代码(rslib/lib.rs)
#[no_mangle] /* 导出为"func" */ pub extern fn func() { // 这里写你的函数逻辑 }
应用代码(app/main.rs)
#[link(name="rslib.dll", kind="dylib")] extern { fn func(); } fn main() { unsafe { func(); } }
这个示例可以正常编译并运行,因为#[no_mangle]阻止了Rust对函数名进行混淆,导出的符号就是清晰的func,应用代码能准确找到它。
无法运行的示例(链接失败)
库代码(rslib/lib.rs)
pub extern fn func() { // 这里写你的函数逻辑 }
如果使用和上面相同的app/main.rs代码,编译时会触发链接错误,错误信息如下:
error LNK2019: unresolved external symbol __imp_func referenced in function _ZN8rust_app4main17h52189e261ef80b93E
原因很简单:没有添加#[no_mangle]属性时,Rust会自动对函数名进行混淆处理,导出的符号不再是func,导致应用代码里的func找不到对应的外部符号,最终链接失败。
内容的提问来源于stack exchange,提问作者K. Mihaylov
相关产品推荐
相关产品推荐

