After messing around webassembly and raylib, I am now trying to figure out how to link some non-zig libraries. So far, I have successfully loaded a dynamic library (.dll/.so), but I have gotten some issues on calling the functions.
The library I was trying to use is called the SunVox Library which is used for controlling a backend of SunVox which is a music tracker.
Initially, I need to call an init function “sv_init” to initialize the library which the function pointer as shown:
// This is generated from cimport.zig after compilation
pub extern var sv_init: ?*const fn ([*c]const u8, c_int, c_int, u32) callconv(.C) c_int;
Based on the required arguments, I have created a wrapper function:
fn sv_init(config: [*c]const u8, sample_rate: i32, channels: i32, flags: u32) !i32 {
const status = sunvox.sv_init.?(config, @as(c_int, sample_rate), @as(c_int, channels), flags);
if (status < 0) {
return SUNVOX_ERR.initialization_failed;
} else {
return @as(i32, status);
}
}
With the function, I wrote the following codes in my main function:
const std = @import("std");
const sunvox = @cImport({
@cInclude("sunvox.h");
});
const SUNVOX_ERR = error{
initialization_failed,
open_slot_failed,
maximum_slot_exceeded,
project_load_failed,
playback_failed,
};
pub fn main() !void {
_ = try sv_init("", 44100, 2, 0);
}
When I build the project, the compiler didn’t throw any error; however, when I run the program, it throws me an Segmentation fault as shown:
Segmentation fault at address 0xffffffffffffffff
...\dynamic_libraries_test\src\main.zig:21:20: 0x913b6 in main (dynamic_libraries_test.exe.obj)
_ = try sv_init(0, 44100, 2, 0);
^
C:\ProgramData\chocolatey\lib\zig\tools\zig-windows-x86_64-0.13.0\lib\std\start.zig:497:75: 0x9190b in main (dynamic_libraries_test.exe.obj)
return callMainWithArgs(@as(usize, @intCast(c_argc)), @as([*][*:0]u8, @ptrCast(c_argv)), envp);
^
C:\ProgramData\chocolatey\lib\zig\tools\zig-windows-x86_64-0.13.0\lib\libc\mingw\crt\crtexe.c:267:0: 0x105c11 in __tmainCRTStartup (crt2.obj)
mainret = _tmain (argc, argv, envp);
C:\ProgramData\chocolatey\lib\zig\tools\zig-windows-x86_64-0.13.0\lib\libc\mingw\crt\crtexe.c:188:0: 0x105c6b in mainCRTStartup (crt2.obj)
ret = __tmainCRTStartup ();
???:?:?: 0x7ffe4d56259c in ??? (KERNEL32.DLL)
???:?:?: 0x7ffe4e22af37 in ??? (ntdll.dll)
Based on the address, I thought it was something done with null reference, so I decided to wrap an optional check as shown:
if (sunvox.sv_init) |func| {
const status = func(config, @as(c_int, sample_rate), @as(c_int, channels), flags);
if (status < 0) {
return SUNVOX_ERR.initialization_failed;
} else {
return @as(i32, status);
}
} else {
return SUNVOX_ERR.initialization_failed;
}
Nevertheless, the optional wasn’t appeared as null, and the same error persists, so I guess it could be the arguments of the function call, but not sure how it exactly happens. Thus, I wanna know what are the possible causes for the Segmentation fault in this case.
I know this question might be too vague, so let me know if anyone want more details about this problem.