Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在Ada中处理int**?_C_Pass By Reference_Ada_Memory Address_Ffi - Fatal编程技术网

C 如何在Ada中处理int**?

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

我试图使用一个预先制作好的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语言中函数的原型:

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;
您可以定义(或使用,如果已经定义)类似my
Raw
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);