What does extern "..." do?

When declaring kernel32 functions, I can omit "kernel32" in the extern declaration, and I don’t even need to pass the -lkernel32 flag. Similarly, for libc functions, I can omit "c" in the extern declaration. As long as I pass the -lc flag, everything works.

So what is the purpose of the extern "..." syntax?

It lets you specify what library/object the symbol is from extern "lib". Useful if multiple linked objects have conflicting symbol names.

Ofc you can’t grab both in the same namespace as you then have the same issue in zig land.

But you can get around that by using @extern which lets you declare the zig name and the linked symbol name separately. Though using separate namespaces is generally a better solution.

1 Like

dll1.c

__declspec(dllexport)
void a() { puts("dll1.a"); }

__declspec(dllexport)
void b() { puts("dll1.b"); }

dll2.c

__declspec(dllexport)
void a() { puts("dll2.a"); }

__declspec(dllexport)
void b() { puts("dll2.b"); }

dll1.zig

pub extern "dll1" fn a() void;

dll2.zig

pub extern "dll2" fn b() void;

main.zig

const dll1 = @import("dll1.zig");
const dll2 = @import("dll2.zig");

pub fn main() void {
  dll1.a();
  dll2.b();
}

// output:
// dll1.a
// dll1.b

Shouldn’t this print dll1.a and dll2.b?