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 = ∈
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
next 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