I'm trying to call SDL_LoadWAV using a pre-made binding to the C library from which it comes. SDL_LoadWAV is just a wrapper for SDL_LoadWAV_RW:
function SDL_LoadWAV (file : C.char_array; spec : access SDL_AudioSpec; audio_buf : System.Address; audio_len : access Uint32) return access SDL_AudioSpec is begin return SDL_LoadWAV_RW (SDL_RWFromFile (file, C.To_C ("rb")), 1, spec, audio_buf, audio_len); end SDL_LoadWAV; Here is the prototype of the function in C:
SDL_AudioSpec* SDL_LoadWAV_RW(SDL_RWops* src, int freesrc, SDL_AudioSpec* spec, Uint8** audio_buf, Uint32* audio_len) (See here for more information)
Now as you can see, it passes a Uint8 (unsigned 8-bit integer) array by reference, in the form of a Uint8**. This is causing me a great bit of vexation. Here is the appropriate binding:
function SDL_LoadWAV_RW (src : access SDL_RWops; freesrc : C.int; spec : access SDL_AudioSpec; audio_buf : System.Address; audio_len : access Uint32) return access SDL_AudioSpec; pragma Import (C, SDL_LoadWAV_RW, "SDL_LoadWAV_RW"); As you can see, the binding maps the Uint8** to a System.Address. I've tried a couple of tricks to get that data where I want it to go, but nothing seems to work. Right now, my code looks like this (it has a few custom types and exceptions in it):
type Music is new Resource with record --Id : Integer; (Inherited from Resource) --Filename : Unbounded_String; (Inherited from Resource) --Archive_Name : Unbounded_String; (Inherited from Resource) --Zzl_Size : Integer; (Inherited from Resource) Audio : access SDL_AudioSpec_Access; Length : aliased Uint32; Buffer : System.Address; Position : Integer := 1; end record; overriding procedure Load(Mus : in out Music) is Double_Pointer : System.Address; begin Log("Loading music " & To_Ada(Get_Audio_Filepath(Mus))); Audio_Load_Lock.Seize; if null = SDL_LoadWAV(Get_Audio_Filepath(Mus), Mus.Audio.all, Double_Pointer, Mus.Length'access) then raise Audio_Load_Failed with To_String(Mus.Filename) & "&Stack=" & Get_Call_Stack; end if; Log("Music length =" & Integer'Image(Integer(Mus.Length))); declare type Sample_Array is array(1..Mus.Length) of Uint8; Single_Pointer : System.Address; for Single_Pointer'address use Double_Pointer; pragma Import(Ada, Single_Pointer); Source : Sample_Array; for Source'address use Single_Pointer; pragma Import(Ada, Source); Dest : Sample_Array; for Dest'address use Mus.Buffer; pragma Import(Ada, Dest); begin Dest := Source; end; Audio_Load_Lock.Release; end Load; But, like more or less everything else I've tried, I get a PROGRAM_ERROR/EXCEPTION_ACCESS_VIOLATION when the Load function is executed.
Can anyone figure out how I need to handle this System.Address? Thanks!