I've been expanding on python version of Armstrong's classical example of interfaces. Everything works fine while I communicate bytes. But, I'd like to communicate long integers and floats. Mabye even (oh, no) strings. Here is my code:
http://pastebin.com/epxgDmvu
http://pastebin.com/rD7CWRkz
First of all, all that I know how to send are bytes. Can erlang send anything else to it's inteface? Or do I have to convert float to list of bytes, send it to python and then assemble it back to float in python?
And, the ohter way around: if I pack with 'f' format, erlang recognises that as a list of bytes. Is there a way to persuade erlang to take those bytes as one single float? If not, where can I find out how to convert that erlang list to erlang float?
In case erlang can communicate only bytes, how do you propose that I send a list of integers? If I convert integers to lists of bytes, then I can't send them in one message since reciever won't know where one integer ends and other begins, right? Should I then send integers one by one?
Yes, I am looking into ErlPort and py-interface and some other, but I'd like to start from fundamentals.
Regards,
dijxtra
At a low (from programming point of view) level you always send/receive only a bunch of bytes through different external interfaces (pipes, network, files...) independently from a programming language you're using. For example when you work with pipes (which you got calling open_port/2) you send/receive data as a stream of bytes.
To send any useful information through a stream you need to divide it to chunks which usually named messages. Message format define how messages can be extracted from a stream of bytes. For example using Type-Length-Value (TLV) encoding you can send values of different length marked with a type.
In ErlPort it all works as following:
- When you call open_port/2 you must add option
{packet, N}
so all binary messages sent through this port are preceded by their length, sent in N bytes (Length-Value encoding).
- Before to send a term to the port you must use term_to_binary/1 function which encode Erlang term to a bunch of bytes using Erlang external term format.
- On Python side when you instantiate erlproto.Port class you must pass the same
packet
value as you pass to open_port/2 (packet=1
by default).
- Port.read method first read the length of the message from the stream and then the message body.
- The message body decoded by the erlterms.decode function.
- When you send a reply using Port.write method it's first encoded to Erlang external term format by erlterms.encode function.
- Then the encoded chunk prepended by its length sent back to Erlang.
- On Erlang side binary_to_term/1 is used to decode the data.