You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将C++ `extern "C" __declspec(dllexport)` 结构体适配为Rust版本用于SKSE64插件

这个需求完全可以实现,针对你遇到的两个核心问题,解决方案如下:


问题1:创建可导出的全局结构体实例

Rust中函数外不能用let声明变量,全局常量/变量需要用static关键字声明,导出规则和函数一致,增加#[no_mangle]和extern "C"修饰即可。额外增加#[used]属性可以避免release模式下编译器优化掉未被Rust代码自身引用的全局变量。

问题2:填充C兼容的固定长度字符串数组

你原来的结构体定义存在类型错误:Rust的char是4字节Unicode类型,和C的1字节char不兼容,需要将字符串字段的类型替换为[u8; 256]。可以写一个const辅助函数将字符串自动转换为带终止符的固定长度u8数组。


完整可运行代码示例

const RUNTIME_VERSION_1_6_318: u32 = 0x010613E0;
const SKSE_PLUGIN_VERSION_DATA_KVERSION: u32 = 1;

// 辅助函数:将字符串转换为固定长度的C风格char数组(自动补0、保证末尾有\0)
const fn str_to_cchar_array<const N: usize>(s: &str) -> [u8; N] {
    let mut arr = [0u8; N];
    let bytes = s.as_bytes();
    let mut i = 0;
    // 最多拷贝N-1位,留最后一位放终止符
    while i < bytes.len() && i < N - 1 {
        arr[i] = bytes[i];
        i += 1;
    }
    arr
}

#[repr(C)]
#[derive(Debug)]
pub struct SKSEPluginVersionData {
    data_version: u32,
    plugin_version: u32,
    name: [u8; 256],
    author: [u8; 256],
    support_email: [u8; 256],
    version_independence: u32,
    compatible_versions: [u32; 16],
    se_version_required: u32,
}

// 导出全局结构体实例
#[no_mangle]
#[used]
pub extern "C" static SKSEPlugin_Version: SKSEPluginVersionData = SKSEPluginVersionData {
    data_version: SKSE_PLUGIN_VERSION_DATA_KVERSION,
    plugin_version: 1,
    name: str_to_cchar_array("Skyrim Search"),
    author: str_to_cchar_array("qbx2 / lukasaldersley"),
    support_email: str_to_cchar_array("something@something.something"),
    version_independence: 0,
    compatible_versions: [
        RUNTIME_VERSION_1_6_318,
        0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0
    ],
    se_version_required: 0,
};

编译完成后可以通过dumpbin /exports 你的dll文件名.dll命令验证是否成功导出SKSEPlugin_Version符号。

内容的提问来源于stack exchange,提问作者lukasaldersley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 20:54:03