In an attempt to follow the YT Series Handmade Hero with Zig, tried to create a Win32 Application Entry Point. The current issues with Zig surrounding Issue #15066 and Issue #7852 be avoided by using the windows.h
header and changing std.zig.c_translation.zig
as I outlined in #15066
First off:
Extern structs / their redefinitions in imported headers and the defined structs (*opaque {};
) are incompatible, so std.os.windows.HWND and the imported c.HWND wont work together:
Slices.zig:149:57: error:
expected type '[*c].cimport.struct_HWND__',
found '*os.windows.HWND__opaque_57354'
var deviceContext: win32.HDC = c.BeginPaint(window, &paint);
^~~~~~
Slices.zig:149:57: note:
pointer type child 'os.windows.HWND__opaque_57354'
cannot cast into pointer type child 'C:.cimport.struct_HWND__'
Zig_w_x86_64_0.12.0-dev.15\lib\std\os\windows.zig:2485:19: note: opaque declared here
pub const HWND = *opaque {};
^~~~~~~~~
cimport.zig:25485:34: note: struct declared here
pub const struct_HWND__ = extern struct {
~~~~~~~^~~~~~
cimport.zig:31861:32: note: parameter type declared here
pub extern fn BeginPaint(hWnd: HWND, lpPaint: LPPAINTSTRUCT) HDC;
So Functions that are cImported need also be fed c extern structs (like c.HWND), although they in theory are the same.
I suppose this is the reason for my actual current bug:
In my wWinMain function:
pub fn wWinMain(instance: win32.HINSTANCE, prevInstance: ?win32.HINSTANCE, commandLine: win32.LPWSTR, showCode: i32) callconv(win32.WINAPI) i32 {...}
I can either pass a std.os.windows.HINSTANCE
or a c.HINSTANCE
from the imported header. Using the std.os.windows.HINSTANCE
produces a compile error, since the cimport.struct_HDC__' cannot cast into pointer type child 'os.windows.HDC__opaque_58145'
(What i mentioned before).
However using the c.HINSTANCE
produces another problem, as std.zig.start
casts the prevInstance: win32.HInstance
into something the wWinMain doesnt like (format might be off):
Zig_w_x86_64_0.12.0-dev.15\lib\std\start.zig:598:43: error: cast increases pointer alignment
const hInstance = @as(MAIN_HINSTANCE, @ptrCast(std.os.windows.kernel32.GetModuleHandleW(null).?));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Zig_w_x86_64_0.12.0-dev.15\lib\std\start.zig:598:98: note: '*os.windows.HMODULE__opaque_55731' has alignment '1'
const hInstance = @as(MAIN_HINSTANCE, @ptrCast(std.os.windows.kernel32.GetModuleHandleW(null).?));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
Zig_w_x86_64_0.12.0-dev.15\lib\std\start.zig:598:43: note: '[*c]C:.cimport.struct_HINSTANCE__' has alignment '4'
Zig_w_x86_64_0.12.0-dev.15\lib\std\start.zig:598:43: note: use @alignCast to assert pointer alignment
Zig_w_x86_64_0.12.0-dev.15\lib\std\start.zig:537:12: note: called from here
return @call(.always_inline, call_wWinMain, .{});
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Zig_w_x86_64_0.12.0-dev.15\lib\std\start.zig:350:67: note: called from here
const result: std.os.windows.INT = initEventLoopAndCallWinMain();
I think this issue is because prevInstance is allways null, but the std.zig.start
process in currently beyond me. Maybe someone knows hoe to handle this ?