使用 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();
}
}
编辑备注
由于 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();
}
}