pass-by-reference - C - 我该如何处理Ada中的int **?

101 4

我正在尝试使用它的C库绑定来调用SDL_LoadWAV。SDL_LoadWAV只是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;



下面是C:中函数的prototype


SDL_AudioSpec* SDL_LoadWAV_RW(SDL_RWops* src,


 int freesrc,


 SDL_AudioSpec* spec,


 Uint8** audio_buf,


 Uint32* audio_len)



现在你可以看到,它以Uint8的形式通过引用传递了一个Uint8 (无符号8位整数)数组,这使我很烦恼,以下是适当的绑定:


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");



如你所见,该绑定将Uint8映射到System Address ,我尝试了一些技巧来获得,我想要的数据,但是看起来没有什么工作,现在,我的代码看起来像这个(它有几个自定义类型和异常):


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;



但是,执行Load函数时,我得到一个PROGRAM_ERROR EXCEPTION_ACCESS_VIOLATION 。

谁能帮我弄清楚如何处理System.Address?谢谢!

时间: 原作者:

60 5

SDL_LoadWAV将在你指定的位置写入缓冲区的内容,即未初始化的变量Double_Pointer的值,该值是一个随机地址-,

在调用SDL_LoadWAV之前,你需要有以下内容:


Double_Pointer := SDL_Buffer'Address;



SDL_Buffer以前被定义为这样的:


type Buffer_Access_Type is access all Buffer_Type;


SDL_Buffer: Buffer_Access_Type;



根据API,你需要在以后使用SDL_FreeWAV释放SDL_Buffer

原作者:
...