1. Passing Floats by Value
- Posted by David Guy <dguy at MINDSPRING.COM> Jan 19, 2000
- 391 views
- Last edited Jan 20, 2000
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
2. Re: Passing Floats by Value
- Posted by Brian Broker <bkb at CNW.COM> Jan 19, 2000
- 373 views
- Last edited Jan 20, 2000
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
3. Re: Passing Floats by Value
- Posted by Robert Craig <rds at ATTCANADA.NET> Jan 19, 2000
- 363 views
- Last edited Jan 20, 2000
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
4. Re: Passing Floats by Value
- Posted by David Guy <dguy at MINDSPRING.COM> Jan 20, 2000
- 369 views
- Last edited Jan 21, 2000
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
5. Re: Passing Floats by Value
- Posted by Robert Craig <rds at ATTCANADA.NET> Jan 21, 2000
- 371 views
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