1. Passing Floats by Value

Hi,

I have a routine in a DLL defined as such:

 EXPORT VOID CALLBACK myFunc( float f0, float f1 )
  {
  printf("%f %f\n", f0, f1 );
  }

I "link" to it from Euphoria like so ('m_DLL' is valid):

 constant m_myFunc = define_c_proc( m_DLL, "_myFunc@8", {C_FLOAT, C_FLOAT})

when I call the routine:

 c_proc( m_myFunc, {1.0, 1.0} )

the following prints out:

 0.000000 0.000000


If I change *JUST* 'C_FLOAT' to 'C_DOUBLE' like so:

 constant m_myFunc = define_c_proc( m_DLL, "_myFunc@8", {C_DOUBLE,C_DOUBLE})

the output becomes:

 0.000000 1.875000


Lastly, if I change *ALL* 'float' to 'double' and *ALL* 'C_FLOAT' 'to
C_DOUBLE' like so:

 EXPORT VOID CALLBACK myFunc( double d0, double d1 )
  {
  printf("%f %f\n", d0, d1 );
  }

 constant m_myFunc = define_c_proc( m_DLL, "_myFunc@16",{C_DOUBLE,C_DOUBLE})

the output becomes, as expected:

 1.000000 1.000000


Now, I'm sure the above has to do with the fact that an ATOM is 8-bytes,
and it *APPEARS* Euphoria is passing 8-bytes per parameter to a routine
that is expecting 4-bytes per parameter.

So the question is:

How do I pass a 4-byte floating point value from Euphoria to a C routine?

(The above code is just a mock up to demonstate my dilemma, in reality the
DLL routine I wish to pass data to is pre-compiled and I don't have access
to the source code, so if I can't figure out how to pass a float, I can't
use the DLL.)

Thanks In Advance,
David

new topic     » topic index » view message » categorize

2. Re: Passing Floats by Value

On Wed, 19 Jan 2000 19:56:53 -0500, David Guy wrote:

>How do I pass a 4-byte floating point value from Euphoria to a C routine?

The include file 'machine.e' has a function called 'atom_to_float32'.
Details of this function are included in the Euphoria reference manual.

-- Brian

new topic     » goto parent     » topic index » view message » categorize

3. Re: Passing Floats by Value

David Guy writes:
> How do I pass a 4-byte floating point value from
> Euphoria to a C routine?

Euphoria only supports passing floating-point atoms to C routines
in the form of C doubles (8 bytes). From my experience,
it's extremely rare that a C routine will pass float arguments
(4-bytes), and even if it did, I believed (until now) that most,
if not all, C compilers automatically promote float arguments
to double before passing them. I suppose I could support
passing atoms as C floats in the next release.

Meanwhile, here's a kludge that you can try.
- convert each argument, a, as:
         a = bytes_to_int(atom_to_float32(a))

- define the C function in Euphoria as if it takes C_INT's
  as arguments

- pass each argument, a, as a C_INT

The bottom line is that you are passing 4 bytes of "something"
for each argument. Euphoria won't care. C won't care.
I'm not totally sure that it will work (maybe the byte-order
is wrong), but it's worth a try.

Regards,
     Rob Craig
     Rapid Deployment Software
     http://www.RapidEuphoria.com

new topic     » goto parent     » topic index » view message » categorize

4. Re: Passing Floats by Value

On Wed, 19 Jan 2000 21:13:26 -0500, Robert Craig <rds at ATTCANADA.NET> wrote:

>David Guy writes:
>> How do I pass a 4-byte floating point value from
>> Euphoria to a C routine?
>
>Euphoria only supports passing floating-point atoms to C routines
>in the form of C doubles (8 bytes). From my experience,
>it's extremely rare that a C routine will pass float arguments
>(4-bytes), and even if it did, I believed (until now) that most,
>if not all, C compilers automatically promote float arguments
>to double before passing them. I suppose I could support
>passing atoms as C floats in the next release.
>
>Meanwhile, here's a kludge that you can try.
>- convert each argument, a, as:
>         a = bytes_to_int(atom_to_float32(a))
>
>- define the C function in Euphoria as if it takes C_INT's
>  as arguments
>
>- pass each argument, a, as a C_INT

You're kludge works! :)

If I "link" to the routine in either of the following ways:

  constant m_myFunc = define_c_proc(m_DLL, "_myFunc@8", {C_FLOAT, C_FLOAT})
    or
  constant m_myFunc = define_c_proc(m_DLL, "_myFunc@8", {C_INT, C_INT})

and then call the routine like so:

  c_proc(m_myFunc,
    {bytes_to_int(atom_to_float32(1.0)),
     bytes_to_int(atom_to_float32(1.0))} )

the following prints out:

 1.000000 1.000000


As to supporting the passing of atoms as C floats,...YES please do!
It would be nice if when a float was specified, a float was passed. :)
It can't be that difficult for Euphoria to convert an atom down to a float
before passing it, and I'm sure it would be much faster, and certainly
cleaner and more straight forward, than the above kludge.

Thanks for the help,
David Guy

new topic     » goto parent     » topic index » view message » categorize

5. Re: Passing Floats by Value

David Guy writes:
> As to supporting the passing of atoms as C floats,...YES please do!

OK. It's quite easy to add. I just didn't realize it
would be useful.

I'm glad the kludge worked.

Regards,
     Rob Craig
     Rapid Deployment Software
     http://www.RapidEuphoria.com

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu