comp.lang.ada
 help / color / mirror / Atom feed
From: Jeffrey Carter <spam@spam.com>
Subject: Re: how to declare a accss type in ada as C's generic pointer
Date: Fri, 10 Dec 2004 01:02:05 GMT
Date: 2004-12-10T01:02:05+00:00	[thread overview]
Message-ID: <hA6ud.6489$yr1.4798@newsread3.news.pas.earthlink.net> (raw)
In-Reply-To: <cp8s17$u2$1@netnews.hinet.net>

bubble wrote:
> 
> enum message_type{singer_name=6,music_size=7,playTime=11}
> int querySongStatus(int message_type,char * message ,int
> max_message_length,int * message_length,void * Num);
> 
> in Ada.I rewrite it and import it to ada. such as
> 
> package work is
>  pragma Liner_Options("-lmymusic32");
>  type message_type is (singer_name,music_size,play_time);
>  subtype myString is string(1..300);
>  type mystring_access is access all mystring;
>  type integer_access is access all integer;
>  function query_Song_Status(
>                msg_type:message_type;
>                message:mystring;
>                max_message_length:integer;
>                message_length:integer_access;
>                Num:System.address);
>  pragma Conversion(C,mystring);
>  pragma COnversion(C,integer_access);
>  pragma import(Stdcall,query_Song_Status,"querySongStatus");
> private
>  for message_Type use (
>   singer_name=>6;
>   music_size=>7;
>   playTime=>11);
> end work;
> 
> in C,if I want to query singer name then
>  char * name = (char *)malloc (sizeof(char) * 300);
>  int length=0;
>  //I must pass a char pointer to querySongStatus..
>  querySongStatus(singer_name,name,300,&length,null);
> else if I want to query song's disk size then
>  int diskByte=0;
>  //I must pass a integer pointer to last parameter
>  querySongStatus(music_size,null,0,null,&diskByte);
> else if I want to query a song's play time then
>  float totalTime;
>  //I must pass float pointer to last parameter
>  querySongStatus(playTime,null,0,0,&totalTime);
> 
> the last parameter is generic pointer,
> the C's function will cast the generic pointer to another type pointer
> according to what the first parameter is?

There are a lot of options, but probably the best is to hide the control 
coupling:

procedure Query (Singer_Name : out String; Last : out Natural);
procedure Query (Size : out Natural);
procedure Query (Play_time : out Float);

Each of these would call the same C function, but declared differently 
in Ada:

type Dummy_Ptr is access all Integer;
pragma Convention (C, Dummy_Ptr);

procedure Query (Singer_Name : out String; Last : out Natural) is
    use Interfaces.C;

    Kind_Value : constant := 6;

    function C_Query (Kind        : Int;
                      Name        : Char_Array;
                      Name_Length : Int;
                      Length      : access Int;
                      Dummy       : Dummy_Ptr := null)
    return Int;
    pragma Import (Stdcall, C_Query, "querySongStatus");

...

    Result := C_Query (Kind_Value, Buffer, Buffer'Length, Length'access);

For the other versions, you'd use Dummy_Ptr for the Name and Length 
parameters, and an appropriate access parameter with an appropriate name 
for the last parameter:

    function C_Query (Kind : Int;
                      D1   : Dummy_Ptr;
                      D2   : Int;
                      D3   : Dummy_Ptr;
                      Size : access Int) return Int;

    Result := C_Query (Kind_Value, null, 0, null, Local'access);

-- 
Jeff Carter
"Blessed are they who convert their neighbors'
oxen, for they shall inhibit their girth."
Monty Python's Life of Brian
83



  reply	other threads:[~2004-12-10  1:02 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-12-09  6:29 how to declare a accss type in ada as C's generic pointer bubble
2004-12-10  1:02 ` Jeffrey Carter [this message]
2004-12-15 13:48 ` David Botton
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox