[erlang-questions] Problem with using Port drivers - need advice

Dmitriy Gorbenko bazil@REDACTED
Fri Sep 7 21:55:28 CEST 2007

Hi all.

I am a beginner in erlang, so I go to
http://erlang.org//doc/tutorial/part_frame.html, find there chapter "6
Port drivers", and tries to compile entire chain.

At first, I guess it is a mistake:

unix> gcc -o exampledrv -fpic -shared complex.c port_driver.c

I think must be wrote like this:

unix> gcc -o example_drv -fpic -shared complex.c port_driver.c

Well, I create C source file, and tries to compile it:

bazil@REDACTED ~/try/erl $ cat so_file.c

#include <stdio.h>
#include "erl_driver.h"

int foo(int x) {
  return x+1;

int bar(int y) {
  return y*2;

typedef struct {
    ErlDrvPort port;
} example_data;

static ErlDrvData example_drv_start(ErlDrvPort port, char *buff)
    example_data* d = (example_data*)driver_alloc(sizeof(example_data));
    d->port = port;
    return (ErlDrvData)d;

static void example_drv_stop(ErlDrvData handle)

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);

ErlDrvEntry example_driver_entry = {
    NULL,                       // F_PTR init, N/A
    example_drv_start,          // L_PTR start, called when port is opened
    example_drv_stop,           // F_PTR stop, called when port is closed
    example_drv_output,         // F_PTR output, called when erlang has sent
    NULL,                       // F_PTR ready_input, called when input
descriptor ready
    NULL,                       // F_PTR ready_output, called when
output descriptor ready
    "example_drv",              // char *driver_name, the argument to
    NULL,                       // F_PTR finish, called when unloaded
    NULL,                       // F_PTR control, port_command callback
    NULL,                       // F_PTR timeout, reserved
    NULL                        // F_PTR outputv, reserved

DRIVER_INIT(example_drv) // must match name in driver_entry
    return &example_driver_entry;
bazil@REDACTED ~/try/erl $ gcc -o example_drv -fpic -shared so_file.c
bazil@REDACTED ~/try/erl $

Next, goes Erlang code:

bazil@REDACTED ~/try/erl $ cat test.erl

-export([start/1, stop/0, init/1]).
-export([foo/1, bar/1]).

start(SharedLib) ->
    case erl_ddll:load_driver(".", SharedLib) of
        ok -> ok;
        {error, already_loaded} -> ok;
        _ -> exit({error, could_not_load_driver})
    spawn(?MODULE, init, [SharedLib]).

init(SharedLib) ->
    register(complex, self()),
    Port = open_port({spawn, SharedLib}, []),

stop() ->
    complex ! stop.

foo(X) ->
    call_port({foo, X}).
bar(Y) ->
    call_port({bar, Y}).

call_port(Msg) ->
    complex ! {call, self(), Msg},
        {complex, Result} ->

loop(Port) ->
        {call, Caller, Msg} ->
            Port ! {self(), {command, encode(Msg)}},
                {Port, {data, Data}} ->
                    Caller ! {complex, decode(Data)}
        stop ->
            Port ! {self(), close},
                {Port, closed} ->
        {'EXIT', Port, Reason} ->
            io:format("~p ~n", [Reason]),

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

decode([Int]) -> Int.
bazil@REDACTED ~/try/erl $

Then, running test.erl:
bazil@REDACTED ~/try/erl $ erl -name f3t@REDACTED
Erlang (BEAM) emulator version 5.5.5 [source] [64-bit] [async-threads:0]

Eshell V5.5.5  (abort with ^G)
(f3t@REDACTED)1> c(test).
(f3t@REDACTED)2> test:start("example_drv").
** exited: {error,could_not_load_driver} **
User switch command
 --> q
bazil@REDACTED ~/try/erl $ 

Could anyone help me ?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 2244 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20070907/bf2cb428/attachment.bin>

More information about the erlang-questions mailing list