mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-05-04 00:32:40 +03:00
Merge pull request 'Export wrapper around Zig DllMain function when linking libc + add tests' (#32179) from squeek502/zig:windows-dlls into master
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/32179 Reviewed-by: Andrew Kelley <andrew@ziglang.org>
This commit is contained in:
+13
-1
@@ -23,6 +23,10 @@ comptime {
|
||||
const dll_main_crt_startup = if (builtin.abi.isGnu()) "DllMainCRTStartup" else "_DllMainCRTStartup";
|
||||
if (native_os == .windows and !builtin.link_libc and !@hasDecl(root, dll_main_crt_startup)) {
|
||||
@export(&DllMainCRTStartup, .{ .name = dll_main_crt_startup });
|
||||
} else if (native_os == .windows and builtin.link_libc and @hasDecl(root, "DllMain")) {
|
||||
if (!@typeInfo(@TypeOf(root.DllMain)).@"fn".calling_convention.eql(.winapi)) {
|
||||
@export(&DllMain, .{ .name = "DllMain" });
|
||||
}
|
||||
}
|
||||
} else if (builtin.output_mode == .Exe or @hasDecl(root, "main")) {
|
||||
if (builtin.link_libc and @hasDecl(root, "main")) {
|
||||
@@ -82,12 +86,20 @@ fn DllMainCRTStartup(
|
||||
}
|
||||
|
||||
if (@hasDecl(root, "DllMain")) {
|
||||
return root.DllMain(hinstDLL, fdwReason, lpReserved);
|
||||
return root.DllMain(@ptrCast(hinstDLL), fdwReason, lpReserved);
|
||||
}
|
||||
|
||||
return .TRUE;
|
||||
}
|
||||
|
||||
fn DllMain(
|
||||
hinstDLL: std.os.windows.HINSTANCE,
|
||||
fdwReason: std.os.windows.DWORD,
|
||||
lpReserved: std.os.windows.LPVOID,
|
||||
) callconv(.winapi) std.os.windows.BOOL {
|
||||
return root.DllMain(@ptrCast(hinstDLL), fdwReason, lpReserved);
|
||||
}
|
||||
|
||||
fn wasm_freestanding_start() callconv(.c) void {
|
||||
// This is marked inline because for some reason LLVM in
|
||||
// release mode fails to inline it, and we want fewer call frames in stack traces.
|
||||
|
||||
@@ -139,4 +139,75 @@ pub fn build(b: *std.Build) void {
|
||||
_ = exe.getEmittedBin();
|
||||
test_step.dependOn(&exe.step);
|
||||
}
|
||||
|
||||
const load_dll_exe = b.addExecutable(.{ .name = "load_dll", .root_module = b.createModule(.{
|
||||
.root_source_file = b.path("loaddll.zig"),
|
||||
.target = target,
|
||||
.optimize = .Debug,
|
||||
}) });
|
||||
|
||||
{
|
||||
const dll = b.addLibrary(.{
|
||||
.name = "zig_dllmain",
|
||||
.linkage = .dynamic,
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("dllmain.zig"),
|
||||
.target = target,
|
||||
.optimize = .Debug,
|
||||
}),
|
||||
});
|
||||
|
||||
const run = b.addRunArtifact(load_dll_exe);
|
||||
run.addArtifactArg(dll);
|
||||
run.expectStdErrEqual("hello from DllMain");
|
||||
run.expectStdOutEqual("");
|
||||
run.expectExitCode(0);
|
||||
run.skip_foreign_checks = true;
|
||||
|
||||
test_step.dependOn(&run.step);
|
||||
}
|
||||
|
||||
{
|
||||
const dll = b.addLibrary(.{
|
||||
.name = "zig_dllmain_link_libc",
|
||||
.linkage = .dynamic,
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("dllmain.zig"),
|
||||
.target = target,
|
||||
.optimize = .Debug,
|
||||
.link_libc = true,
|
||||
}),
|
||||
});
|
||||
|
||||
const run = b.addRunArtifact(load_dll_exe);
|
||||
run.addArtifactArg(dll);
|
||||
run.expectStdErrEqual("hello from DllMain");
|
||||
run.expectStdOutEqual("");
|
||||
run.expectExitCode(0);
|
||||
run.skip_foreign_checks = true;
|
||||
|
||||
test_step.dependOn(&run.step);
|
||||
}
|
||||
|
||||
{
|
||||
const dll = b.addLibrary(.{
|
||||
.name = "c_dllmain",
|
||||
.linkage = .dynamic,
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = .Debug,
|
||||
.link_libc = true,
|
||||
}),
|
||||
});
|
||||
dll.root_module.addCSourceFile(.{ .file = b.path("dllmain.c") });
|
||||
|
||||
const run = b.addRunArtifact(load_dll_exe);
|
||||
run.addArtifactArg(dll);
|
||||
run.expectStdErrEqual("hello from DllMain");
|
||||
run.expectStdOutEqual("");
|
||||
run.expectExitCode(0);
|
||||
run.skip_foreign_checks = true;
|
||||
|
||||
test_step.dependOn(&run.step);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
|
||||
if (fdwReason == DLL_PROCESS_ATTACH) {
|
||||
fprintf(stderr, "hello from DllMain");
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
const std = @import("std");
|
||||
const windows = std.os.windows;
|
||||
|
||||
const DLL_PROCESS_ATTACH = 1;
|
||||
|
||||
pub fn DllMain(
|
||||
hinstDLL: windows.HINSTANCE,
|
||||
fdwReason: windows.DWORD,
|
||||
lpReserved: windows.LPVOID,
|
||||
) windows.BOOL {
|
||||
_ = hinstDLL;
|
||||
_ = lpReserved;
|
||||
switch (fdwReason) {
|
||||
DLL_PROCESS_ATTACH => std.debug.print("hello from DllMain", .{}),
|
||||
else => {},
|
||||
}
|
||||
return .TRUE;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
const std = @import("std");
|
||||
const windows = std.os.windows;
|
||||
|
||||
extern "kernel32" fn LoadLibraryW(windows.LPCWSTR) callconv(.winapi) ?windows.HMODULE;
|
||||
|
||||
pub fn main(init: std.process.Init) !void {
|
||||
const arena = init.arena.allocator();
|
||||
const args = try init.minimal.args.toSlice(arena);
|
||||
if (args.len < 2) return error.NoDllPathSpecified;
|
||||
const dll_path = args[1];
|
||||
const dll_path_w = try std.unicode.wtf8ToWtf16LeAllocZ(arena, dll_path);
|
||||
_ = LoadLibraryW(dll_path_w) orelse return error.FailedToLoadDll;
|
||||
}
|
||||
Reference in New Issue
Block a user