Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

erlang interface to python

Tags:

python

erlang

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

like image 726
dijxtra Avatar asked Feb 19 '11 12:02

dijxtra


1 Answers

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.
like image 197
hdima Avatar answered Nov 03 '22 21:11

hdima