driver_output_term() and unsigned long (32 bit) values
Shawn Pearce
spearce@REDACTED
Tue Jul 23 04:49:23 CEST 2002
I'm getting around this with #2 right now. Its not a big deal,
as its a group of unsigned ints already stored in a C struct.
Format of the struct is part of the "contract" between my port server
in Erlang and my C code. Its ugly, but its working just fine.
Of course, ugly is 68 lines of extremely commented Erlang code. ;-)
The more interesting thing missing from driver_output_term is a way
to send a floating point number. Just figure that one out. :-)
Currently I'm constructing an integer which is the actual value
times the number of decimal places I need (100 to make 12.45 1245),
and dividing it in Erlang after converting it to a float with float/1.
Its a good thing I don't need to represent a large number of decimal
places, or large values.
Looking at the extensions since 4.4 docs however, I see that it may
be possible to use << F:64/float >> to pass my floating point information
up to Erlang. However, what floating point representation is this in?
Docs don't seem to say.
The other way to do this would be to use erl_interface to convert the
floats into the external format, send that as a binary with
driver_output_term() and let Erlang convert it back with binary_to_term/1.
I noticed that for endianness << >> supports big and little, but
doesn't support "host". This would be really nice, as there is otherwise
no way to just have Erlang read my C struct from the driver. Instead, the
driver must convert everything back and forth using ntohl() and Erlang
does the same conversion. I can see though how this option could easily
get you into trouble when you distribute an application.
IMHO, driver_output_term is simple enough to get most of what is needed,
the rest can be trivially hacked with a little bit of glue code in Erlang.
Since the port itself should be hidden through either a module or a server
process, its not to bad programmatically either.
But these little conversions can add up in both speed and accuracy fast...
Scott Lystig Fritchie <fritchie@REDACTED> scrawled:
> Am I correct in assuming that, if I *really* needed a driver to get
> the most-significant bit of a 32 bit unsigned long sent to Erlang via
> driver_output_term(), I'm out of luck?
>
> I suppose I could do something like:
>
> 1. Modify BEAM to support unsigned integers.
> 2. Send the unsigned int back as a binary and then unpack it as an
> ":32/unsigned-integer"
> 3. Send the unsigned int back as a signed int, then have Erlang pack
> it into a binary and then unpack it as a ":32/unsigned-integer".
> 4. Send back a {1, N} tuple and then have Erlang convert via "(1 bsl
> 31) bor N" or equivalent arithmetic.
> 5. Not use driver_output_term().
> 6. Um, I think I'd better stop now. This is getting too ugly.
>
> Is there a better, non-ugly solution I'm missing?
--
Shawn.
Why do I like Perl? Because ``in accordance with Unix tradition Perl
gives you enough rope to hang yourself with.''
Why do I dislike Java? Because ``the class ROPE that should contain the
method HANG to do the hanging doesn't exist because there is too much
'security' built into the base language.''
More information about the erlang-questions
mailing list