zig icon indicating copy to clipboard operation
zig copied to clipboard

Cannot `@cImport` `windows.h` when targetting `msvc` abi

Open ofrank123 opened this issue 1 year ago • 6 comments

Zig Version

0.12.0

Steps to Reproduce and Observed Behavior

The following program:

const win = @cImport(@cInclude("windows.h"));

pub fn main() void {
    _ = win;
}

Fails to compile, using zig run -target x86_64-windows-msvc -lc .\main.zig:

C:\Users\olive\AppData\Local\zig\o\d6a404198b68dc019984cda1821a66b4\cimport.zig:71000:50: error: use of undeclared identifier 'struct_DECLSPEC_UUID'
pub inline fn MIDL_INTERFACE(x: anytype) @TypeOf(struct_DECLSPEC_UUID(x)) {
                                                 ^~~~~~~~~~~~~~~~~~~~
main.zig:1:13: error: C import failed: AnalysisFail
const win = @cImport(@cInclude("windows.h"));
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
    main: main.zig:4:9
    callMain: C:\bin\lib\std\start.zig:501:17
    remaining reference traces hidden; use '-freference-trace' to see all reference traces

Expected Behavior

It should compile

ofrank123 avatar May 25 '24 11:05 ofrank123

There are reasons including windows.h does not work (perhaps someone can elaborate why).

The following may be of interest to you: https://www.youtube.com/watch?v=HsnWZxrf5VE https://github.com/marlersoft/zigwin32

I am not sure if the solution for interfacing with windows as described there, has been kept up to date all the way up to the present.

mjmlvp avatar May 25 '24 13:05 mjmlvp

It works fine using mingw in my experience, does mingw ship their own windows.h? But thanks for the links, I'll check it out

ofrank123 avatar May 25 '24 19:05 ofrank123

As a workaround, you can write bindings for the APIs you need, similar to those in the standard library:

https://github.com/ziglang/zig/blob/master/lib/std/os/windows/kernel32.zig#L72

or you can use https://github.com/marlersoft/zigwin32/ for autogenerated bindings.

The benefit of this approach is that you no longer need to link libc (if you're only linking it for windows.h), and your program will only depend on the DLLs that it actually uses.

squeek502 avatar May 25 '24 23:05 squeek502

Thanks @squeek502, that's a good point. It'd be nice not to have to depend on libc as I don't really use it. I'll look into moving my codebase to use this strategy.

ofrank123 avatar May 26 '24 19:05 ofrank123

@ofrank123 yes, mingw ships their own headers. the reason this only happens on msvc & not mingw is because the windows SDK defines MIDL_INTERFACE like so:

#define MIDL_INTERFACE(x) struct DECLSPEC_UUID(x) DECLSPEC_NOVTABLE

while mingw just defines it as struct. as a simple workaround, if you define MIDL_INTERFACE like mingw does:

zig build-exe -target x86_64-windows-msvc -DMIDL_INTERFACE=struct -lc .\test.zig

then code that imports windows.h compiles fine.

nihilx7e3 avatar May 27 '24 03:05 nihilx7e3

Thanks for the heads up @nihil-2019!

ofrank123 avatar May 28 '24 22:05 ofrank123

Note: you can add @cDefine("MIDL_INTERFACE", "struct"); inside your @cImport({});

emidoots avatar Jun 02 '24 23:06 emidoots