comp.lang.ada
 help / color / mirror / Atom feed
From: deadlyhead <deadlyhead@gmail.com>
Subject: Access to C_float wipes out float value
Date: Thu, 19 Aug 2010 18:40:18 -0700 (PDT)
Date: 2010-08-19T18:40:18-07:00	[thread overview]
Message-ID: <e42a0d91-535b-4f75-8ae6-58238a51d84c@x24g2000pro.googlegroups.com> (raw)

I'm in the unfortunate position of needing to interface to code which
deals heavily with void* c types and functions.  In order to get to
grips with this, I've written two small files whereby I created a
function which returns a void* in C, and in Ada this value is
converted to an Access type (depending on the input to the C
function), and it's .all value is then displayed.

The code:

/*************************** Begin C code ***************************/

#include "stdio.h"

void*
do_something (int get_float)
{

  int*   i;
  float* f;

  int in = 12345;
  float fl = 9876.54321;

  f = &fl;
  i = &in;

  if (!get_float) {
    printf ("Value of \"*i\" is %d\n", *i);
    return i;
  } else {
    printf ("Value of \"*f\" is %f\n", *f);
    return f;
  }
}

/**************************** End C code ****************************/

--------------------------- Begin Ada code ---------------------------

with Ada.Text_IO;         use Ada.Text_IO;

with System;
with System.Address_To_Access_Conversions;
with Interfaces.C;

procedure Void_Stuff is

   package C renames Interfaces.C;

   subtype Void_Ptr is System.Address;

   package Int_ATAC is new System.Address_To_Access_Conversions
     (Object => C.int);

   package Flt_ATAC is new System.Address_To_Access_Conversions
     (Object => C.C_float);


   package Int_IO is new Integer_IO (C.int);
   use Int_IO;

   package C_Float_IO is new Float_IO (C.C_float);
   use C_Float_IO;

   use Int_ATAC;
   use FLT_ATAC;

   type C_Bool is  (False, True);
   for  C_Bool use (False => 0, True => 1);
   pragma Convention (C, C_Bool);

   function Do_Something (Get_Float : C_Bool) return Void_Ptr;
   pragma Import (C, Do_Something, "do_something");

   My_Int : Int_ATAC.Object_Pointer;
   My_Flt : Flt_ATAC.Object_Pointer;

begin

   --  Let's do this
   My_Int := To_Pointer (Do_Something (False));

   Put ("The value of ""My_Int"" is ");
   Put (My_Int.all, Width => 0);
   New_Line;

   My_Flt := To_Pointer (Do_Something (True));
   Put ("The value of ""My_Flt"" is ");
   Put (My_Flt.all);
   New_Line;

end Void_Stuff;

---------------------------- End Ada Code ----------------------------

The output:

Value of "*i" is 12345
The value of "My_Int" is 12345
Value of "*f" is 9876.542969
The value of "My_Flt" is  6.06708E-39      <----- wtf???

I can't think of any way that I messed this up.  There must me
something about float* in C that truly screws them up when treated as
a System.Address in Ada.  I suppose that the safest way would be to
wrap such a function up in a nice, type-safe Ada function where only
one output type is possible and use an ... access Float; type instead,
but _dang_.  I really want to know what's going on here.

Maybe my problem is my dislike of C in general, and a subsequent lack
of understanding?  I plan on implementing a nice thick binding as this
project progresses, so I'll be getting around this anyway.  Thank you
if you can provide any insight, though.

-- deadlyhead



             reply	other threads:[~2010-08-20  1:40 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-20  1:40 deadlyhead [this message]
2010-08-20  2:05 ` Access to C_float wipes out float value (see below)
2010-08-20  2:09 ` Yannick Duchêne (Hibou57)
2010-08-20  2:12   ` deadlyhead
replies disabled

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