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

使用Zig创建无C运行时的32位Windows DLL并移除不必要导出

创建无C运行时依赖的32位Windows Zig DLL

一、解决编译时undefined symbol错误(不依赖C运行时)

不使用-lc时出现未定义符号,是因为默认情况下Zig会尝试链接C运行时的启动代码(_DllMainCRTStartup@12)。要完全脱离CRT,需手动实现DLL入口逻辑,并明确告诉Zig不引入CRT依赖:

  1. 手动实现DllMain入口
    在src/main.zig中添加符合Windows标准的DLL入口函数,使用Stdcall调用约定:

    const std = @import("std");
    const win32 = std.os.windows;
    
    // 自定义DLL入口,替代CRT的_DllMainCRTStartup
    export fn DllMain(dll_module: win32.HMODULE, call_reason: u32, reserved: ?*anyopaque) callconv(.Stdcall) win32.BOOL {
        switch (call_reason) {
            win32.DLL_PROCESS_ATTACH => {
                // 初始化逻辑(如分配资源)
            },
            win32.DLL_PROCESS_DETACH => {
                // 清理逻辑(如释放资源)
            },
            else => {},
        }
        return win32.TRUE;
    }
    
    // 自定义导出函数示例
    export fn add(a: i32, b: i32) callconv(.Stdcall) i32 {
        return a + b;
    }
    
  2. 使用正确的编译命令
    加上--no-libc参数禁用C运行时链接,最终命令:

    zig build-lib -O ReleaseFast -fstrip -target x86-windows-gnu -dynamic --no-libc src/main.zig
    

二、阻止_DllMainCRTStartup@12被导出

该符号被导出,是因为默认Zig的CRT启动代码(std/start.zig)会将其标记为导出。当你使用--no-libc并手动实现DllMain后,Zig不会生成_DllMainCRTStartup@12符号,自然不会被导出。

若仍有导出问题,需确认:

  • 未误加-lc参数(该参数会重新引入CRT启动代码)
  • 仅通过export关键字标记需要对外暴露的函数(如示例中的add),DLL入口DllMain无需导出——Windows系统会自动识别它作为入口点,不需要通过GetProcAddress调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 21:37:26