erlangerlang-driver

Sending terms instead of iolists to an Erlang driver


Is there an equivalent of driver_output_term in the other direction, i.e. sending an Erlang term to the driver without converting it to an iolist first? If not, I presumably should convert my term using term_to_binary and parse it on the C side with ei; any good examples?


Solution

  • According to the docs, you can only send stuff that's in iodata() format.

    If all you want send to the driver is integers and strings, it might be more efficient (and a lot easier) to use your own term-to-iodata encoding, as in this tutorial from the Erlang documentation. They use a function to convert their calls to a mapping that can be sent to the driver directly and therefore doesn't need to be encoded using term_to_binary().

    encode({foo, X}) -> [1, X];
    encode({bar, Y}) -> [2, Y].
    

    This mapping is feasible if X and Y are assumed to be small integers. On the C side, the first byte of the input buffer is switched upon to call the appropriate function using the second byte as the argument:

    static void example_drv_output(ErlDrvData handle, char *buff, int bufflen)
    {
        example_data* d = (example_data*)handle;
        char fn = buff[0], arg = buff[1], res;
        if (fn == 1) {
            res = foo(arg);
        } else if (fn == 2) {
            res = bar(arg);
        }
        driver_output(d->port, &res, 1);
    }