[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:
-----------8<----------------------------------------------------------------
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)
{
driver_free((char*)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
open_port
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
-I/usr/lib64/erlang/usr/include
bazil@REDACTED ~/try/erl $
-----------8<----------------------------------------------------------------
Next, goes Erlang code:
-----------8<----------------------------------------------------------------
bazil@REDACTED ~/try/erl $ cat test.erl
-module(test).
-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})
end,
spawn(?MODULE, init, [SharedLib]).
init(SharedLib) ->
register(complex, self()),
Port = open_port({spawn, SharedLib}, []),
loop(Port).
stop() ->
complex ! stop.
foo(X) ->
call_port({foo, X}).
bar(Y) ->
call_port({bar, Y}).
call_port(Msg) ->
complex ! {call, self(), Msg},
receive
{complex, Result} ->
Result
end.
loop(Port) ->
receive
{call, Caller, Msg} ->
Port ! {self(), {command, encode(Msg)}},
receive
{Port, {data, Data}} ->
Caller ! {complex, decode(Data)}
end,
loop(Port);
stop ->
Port ! {self(), close},
receive
{Port, closed} ->
exit(normal)
end;
{'EXIT', Port, Reason} ->
io:format("~p ~n", [Reason]),
exit(port_terminated)
end.
encode({foo, X}) -> [1, X];
encode({bar, Y}) -> [2, Y].
decode([Int]) -> Int.
bazil@REDACTED ~/try/erl $
-----------8<----------------------------------------------------------------
Then, running test.erl:
-----------8<----------------------------------------------------------------
bazil@REDACTED ~/try/erl $ erl -name f3t@REDACTED
Erlang (BEAM) emulator version 5.5.5 [source] [64-bit] [async-threads:0]
[kernel-poll:false]
Eshell V5.5.5 (abort with ^G)
(f3t@REDACTED)1> c(test).
{ok,test}
(f3t@REDACTED)2> test:start("example_drv").
** exited: {error,could_not_load_driver} **
(f3t@REDACTED)3>
User switch command
--> q
bazil@REDACTED ~/try/erl $
-----------8<----------------------------------------------------------------
Could anyone help me ?
Thanks.
-------------- 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