const builtin = @import("builtin"); const std = @import("std"); const expect = std.testing.expect; test "anyopaque extern symbol" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; const a = @extern(*anyopaque, .{ .name = "a_mystery_symbol" }); const b: *i32 = @ptrCast(@alignCast(a)); try expect(b.* == 1234); } export var a_mystery_symbol: i32 = 1234; test "function extern symbol" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; const a = @extern(*const fn () callconv(.c) i32, .{ .name = "a_mystery_function" }); try expect(a() == 4567); } export fn a_mystery_function() i32 { return 4567; } test "function extern symbol matches extern decl" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; const S = struct { extern fn another_mystery_function() u32; const same_thing = @extern(*const fn () callconv(.c) u32, .{ .name = "another_mystery_function" }); }; try expect(S.another_mystery_function() == 12345); try expect(S.same_thing() == 12345); } export fn another_mystery_function() u32 { return 12345; } extern fn c_extern_function() [*c]u32; test "coerce extern function types" { const S = struct { export fn c_extern_function() [*c]u32 { return null; } }; _ = S; _ = @as(fn () callconv(.c) ?*u32, c_extern_function); } fn a_function(func: fn () callconv(.c) void) void { _ = func; } test "pass extern function to function" { a_function(struct { extern fn an_extern_function() void; }.an_extern_function); a_function(@extern(*const fn () callconv(.c) void, .{ .name = "an_extern_function" }).*); } export fn an_extern_function() void {}