Erlang Port drivers and Erl_interface

Raimo Niskanen raimo@REDACTED
Fri Jan 28 09:02:13 CET 2005


casper2000a@REDACTED writes:

> Hi Robert,
> 
> This is really good information. Thanks a lot.
> 
> Have you used Port Driver call back functions outputv, event, etc. I have 2 concerns about them. 
> Unfortunately the documentation I found on them are not enough to absorb the full working scenario 
> of them.
> 
> 1) In outputv, the erlang emulator sends the message as a ErlIOVec. I wonder how I can use 
> ei_decode to extract the message.
> 

You can probably not. If the driver has got an outputv callback, it will
be used, and then the emulator does not have to copy binaries that are
sent to the port. If you send a list of binaries mixed with bytes, one
binary will be created to store the bytes, then an ErlIOVec is created
that contains pointers into the binaries - either to the common binary
for the odd bytes, or to the original binaries sent to the port. This
is a way to minimize copying of large amounts of data between the
erlang process and the driver.

> 2) I didn't find a good document on event call back function. What're the information pass in as 
> ErlDrvEvent and ErlDrvEventData?
> 

Have a look at the Erts reference manual, there is some documentation
there.
http://www.erlang.se/doc/doc-5.4.3/erts-5.4.3/doc/html/part_frame.html
sections 3 and 6.

> 3) Have you used anync or enq/deq functions in Port Driver? If you can give me some help or sample 
> would be excellent.
> 
> 4) Please confirm you are discussing above a Port driver, but not a C Node or Erl_Interface based 
> port.
> 
> 5) In your below example, in which call back functions can you call handle_regular_message to 
> decode the function? Could you provide an example call back function.
> 
> Thanks in advance!
> Eranga
> 
> 
> 
> 
> Quoting Robert Raschke : > Quoting Robert Raschke :
> 
> > Hi Eranga,
> > 
> > you wrote:
> > > Let\'s say I want to pass a complex structure back and forth. And I opened
> > > the linked-in driver port using binary. Then can I use term_to_binary and
> > > binary_to_term in the Erlang side and erl_decode, erl_encode and other erl
> > > interface functions in the C side?
> > 
> > I have been using the term_to_binary and binary_to_term functions as
> > well. In my C port program I use the ei_decode...() and
> > ei_encode...() functions. It took me a little bit to get used to the
> > way these functions handle the message buffer, but with a little bit
> > of experimentation you will get up and running quickly.
> > 
> > For example I send my requests from erlang in a predefined format
> > (obviously), and then I unpack it in my C program like this, with the
> > x_in buffer holding a message. It is very verbose, as I was learning
> > how the ei functions work while writing it.
> > 
> > static void
> > handle_regular_message(ei_x_buff *x_in, ei_x_buff *x_out)
> > {
> > int valid = 1;
> > int version;
> > int arity;
> > char call_atom[MAXATOMLEN];
> > erlang_pid from;
> > char fn_atom[MAXATOMLEN];
> > 
> > /*
> > Incoming message has to be
> > {call, Caller_Pid, Fn, [Params]}
> > with
> > call - the atom \'call\'
> > Caller_Pid - erlang pid of process that sent the message
> > Fn - name as atom of the function to invoke
> > Params - parameters to pass to Fn
> > 
> > For an invalid request message the return message has the form
> > {error, badmsg}
> > 
> > For a valid request message the return message has the form
> > {Caller_Pid, Result}
> > with
> > Result = ok | {ok, Value} | {error, internal, error} | {error, badarg,
> > args}
> > */
> > 
> > if (valid && ei_decode_version(x_in->buff, &x_in->index, &version) != 0) {
> > fprintf(stderr, \"Warning: Ignoring received malformed message (bad
> > version).\\n\");
> > valid = 0;
> > }
> > 
> > if (valid && ei_decode_tuple_header(x_in->buff, &x_in->index, &arity) != 0)
> > {
> > fprintf(stderr, \"Warning: Ignoring received malformed message (not
> > tuple).\\n\");
> > valid = 0;
> > }
> > if (valid && arity != 4) {
> > fprintf(stderr, \"Warning: Ignoring received malformed message (not 4-arity
> > tuple).\\n\");
> > valid = 0;
> > }
> > 
> > if (valid && ei_decode_atom(x_in->buff, &x_in->index, call_atom) != 0) {
> > fprintf(stderr, \"Warning: Ignoring received malformed message (first tuple
> > element not atom).\\n\");
> > valid = 0;
> > }
> > if (valid && strcmp(call_atom, \"call\") != 0) {
> > fprintf(stderr, \"Warning: Ignoring received malformed message\"
> > \" (first tuple element not atom \'call\').\\n\");
> > valid = 0;
> > }
> > 
> > if (valid && ei_decode_pid(x_in->buff, &x_in->index, &from) != 0) {
> > fprintf(stderr, \"Warning: Ignoring received malformed message (Second tuple
> > element not pid).\\n\");
> > valid = 0;
> > }
> > 
> > if (valid && ei_decode_atom(x_in->buff, &x_in->index, fn_atom) != 0) {
> > fprintf(stderr, \"Warning: Ignoring received malformed message (Third tuple
> > element not atom).\\n\");
> > valid = 0;
> > }
> > 
> > if (valid) {
> > x_out->index = 0;
> > ei_x_encode_version(x_out);
> > ei_x_encode_tuple_header(x_out, 2);
> > ei_x_encode_pid(x_out, &from);
> > 
> > fprintf(stderr, \"Attempting to call e_%s().\\n\", fn_atom);
> > 
> > if (strcmp(fn_atom, \"my_fun_1\") == 0) my_fun_1(x_in, x_out);
> > else if (strcmp(fn_atom, \"my_fun_2\") == 0) my_fun_2(x_in, x_out);
> > else if (strcmp(fn_atom, \"my_fun_3\") == 0) my_fun_3(x_in, x_out);
> > else {
> > fprintf(stderr, \"Warning: Ignoring received malformed message\"
> > \" (Third tuple element not recognised function).\\n\");
> > valid = 0;
> > }
> > if (valid) {
> > fprintf(stderr, \"Returned from my_fun().\\n\");
> > }
> > }
> > 
> > if (! valid) {
> > x_out->index = 0;
> > ei_x_encode_version(x_out);
> > ei_x_encode_tuple_header(x_out, 2);
> > ei_x_encode_atom(x_out, \"error\");
> > ei_x_encode_atom(x_out, \"badmsg\");
> > }
> > }
> > 
> > Each function I invoke (my_fun()) takes apart the rest of the x_in
> > buffer, and completes the result buffer x_out (which gets sent back to
> > Erlang).
> > 
> > I hope this gets you further along,
> > Robby
> > 
> > 
> 
> --------------This mail sent through OmniBIS.com--------------
> 

-- 

/ Raimo Niskanen, Erlang/OTP, Ericsson AB



More information about the erlang-questions mailing list