如何在Rust中创建含Mangled名称的转发DLL导出函数
在Rust里实现带名称修饰的Windows DLL转发导出
第一种方案:用.def文件+正确链接配置搞定
之前你用.def没生效,大概率是链接器没正确读取.def文件,或者配置写错了。按下面步骤来:
- 写对.def文件
新建myproxy.def,内容直接指定转发关系,注意两边的修饰名必须完全一致(大小写、符号一个都不能错):LIBRARY myproxy.dll EXPORTS ?WriteStuff@CBuffer@@QEAAJPEBG@Z = existing.dll.?WriteStuff@CBuffer@@QEAAJPEBG@Z - 让Rust链接器用上这个.def文件
有两种方式选一个就行:- 改Cargo.toml,加rustflags:
[package] name = "myproxy" version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] [target.'cfg(target_os = "windows")'.build] rustflags = ["-C", "link-arg=/DEF:myproxy.def"] - 用build.rs脚本:
新建build.rs文件,内容如下:fn main() { if cfg!(target_os = "windows") { println!("cargo:rustc-link-arg=/DEF:myproxy.def"); } }
?WriteStuff@CBuffer@@QEAAJPEBG@Z existing.dll:?WriteStuff@CBuffer@@QEAAJPEBG@Z(等号换成空格)。 - 改Cargo.toml,加rustflags:
- 别写空函数了!.def的转发条目会让链接器直接在导出表里生成指向existing.dll的跳转,根本不需要自己写空函数占位置。
第二种方案:用Rust的链接段手动生成转发(偏底层)
如果.def还是不生效,试试直接在代码里构造PE导出表的转发条目:
#[cfg(target_os = "windows")] #[link_section = ".edata$"] #[no_mangle] pub static __exports: [u8; 0] = []; // 构造转发字符串:格式是"目标DLL名\0修饰名\0" #[cfg(target_os = "windows")] #[link_section = ".rdata$zzz"] #[no_mangle] pub static forward_entry: &[u8] = b"existing.dll\0?WriteStuff@CBuffer@@QEAAJPEBG@Z\0";
不过这种方式需要懂PE格式的细节,容易写错,优先用第一种方案。
踩坑排查要点
- 确认用的是MSVC工具链:执行
rustup default stable-x86_64-pc-windows-msvc切换,GNU工具链对.def转发的支持不如MSVC稳定。 - 用
dumpbin /exports existing.dll命令导出existing.dll的所有函数,复制粘贴准确的修饰名,别手敲容易错。 - 检查.def文件的路径:如果放在项目根目录,链接参数里的路径就写
/DEF:myproxy.def,要是在子目录就得写全路径。
内容的提问来源于stack exchange,提问作者Kurosh D.
相关产品推荐
相关产品推荐

