C 如何在Ada中处理int**?
我试图使用一个预先制作好的C库绑定来调用SDL_LoadWAV。SDL_LoadWAV只是SDL_LoadWAV_RW的包装:C 如何在Ada中处理int**?,c,pass-by-reference,ada,memory-address,ffi,C,Pass By Reference,Ada,Memory Address,Ffi,我试图使用一个预先制作好的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 ret
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语言中函数的原型:
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。我尝试了一些技巧来获取数据,但似乎没有任何效果。现在,我的代码如下所示(其中有一些自定义类型和异常):
但是,就像我尝试过的其他方法一样,在执行Load函数时,我会遇到程序错误/异常访问冲突
有人知道我需要如何处理这个系统吗?谢谢 SDL_LoadWAV将在您给定的位置写入一个指针(指向SDL分配的新缓冲区),即未初始化变量Double_pointer的值,它是一个随机地址->kaboom 在调用SDL_LoadWAV之前,您需要有如下内容:
Double_Pointer := SDL_Buffer'Address;
其中,SDL\u Buffer
以前是这样定义的:
type Buffer_Access_Type is access all Buffer_Type;
SDL_Buffer: Buffer_Access_Type;
根据API,您需要稍后使用SDL\u FreeWAV
释放SDL\u缓冲区
如果调用成功,此函数将返回指向SDL_AudioSpec结构的指针,该结构中填充了波源数据的音频数据格式。audio_buf用指向包含音频数据的已分配缓冲区的指针填充,audio_len用该音频缓冲区的长度(以字节为单位)填充
这意味着被调用函数分配并填充所需内存,然后返回指向所分配内存及其长度的指针
所以你提供的装订不是很好
audio\u buf
应该是字节数组的out
参数,audio\u len
应该是out
参数到Uint32
作为演示,使用此C:
#包括
无效获取数据(字符**buf,整数*len)
{
*len=10;
*buf=malloc(*len);
对于(int j=0;j<*len;j++){
(*buf)[j]=j;
}
}
这是艾达
type Raw is array (Interfaces.Unsigned_32) of Interfaces.Unsigned_8
with Convention => C;
定义一个数组类型(如果我们真的声明了一个,它将占用2^32-1字节!),并且
type Raw_P is access all Raw
with Convention => C, Storage_Size => 0;
定义指向此类数组的指针。将存储大小限制为0意味着我们不能说newraw\P
把这些放在一起,
with Ada.Text_IO; use Ada.Text_IO;
with Interfaces;
procedure Demo is
type Raw is array (Interfaces.Unsigned_32) of Interfaces.Unsigned_8
with Convention => C;
type Raw_P is access all Raw
with Convention => C, Storage_Size => 0;
procedure Get_Data (In_Buffer : out Raw_P;
Length : out Interfaces.Unsigned_32)
with
Import,
Convention => C,
External_Name => "get_data";
Allocated : Raw_P;
Length : Interfaces.Unsigned_32;
use type Interfaces.Unsigned_32;
begin
Get_Data (In_Buffer => Allocated,
Length => Length);
for J in 0 .. Length - 1 loop
Put (Allocated (J)'Image);
end loop;
New_Line;
end Demo;
给出一个程序,该程序在运行时产生
$ ./demo
0 1 2 3 4 5 6 7 8 9
$
----
意识到你可能被困在
audio_buf : System.Address;
您可以定义(或使用,如果已经定义)类似myRaw
,Raw\p
的内容,并说
procedure Get_Data (In_Buffer : System.Address;
Length : out Interfaces.Unsigned_32)
with
Import,
Convention => C,
External_Name => "get_data";
然后使用
Get_Data (In_Buffer => Allocated'Address,
Length => Length);
西蒙,你应该得到一枚奖章。困惑的问题,超级简单的解决方案。
Get_Data (In_Buffer => Allocated'Address,
Length => Length);