Пробую способы коннекта Erlang и C кода. C c-node, port, NIF всё ок, по докам запускается и фурычит. А вот с port driver не заводится.
Оф. дока: http://erlang.org/doc/tutorial/c_portdriver.html
/* complex.c */
int foo(int x) {
return x+1;
}
int bar(int y) {
return y*2;
}
/* port_driver.c */
#include <erl_driver.h>
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;
}
Собираю сошку:
gcc -o exampledrv -fpic -shared complex.c port_driver.c
Плюётся тремя варнингами, но не в этом суть. Сошка exampledrv получена и nm -D exampledrv говорит:
000000000000092f T bar
0000000000201130 B __bss_start
w __cxa_finalize
U driver_alloc
U driver_free
0000000000000a2c T driver_init
U driver_output
0000000000201130 D _edata
0000000000201138 B _end
0000000000201080 D example_driver_entry
0000000000000a3c T _fini
0000000000000920 T foo
w __gmon_start__
0000000000000770 T _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
w _Jv_RegisterClasses
U __stack_chk_fail
Окей. Попробуем загрузить драйвер через erl_ddll:load_driver/2.
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [kernel-poll:false]
Eshell V7.0 (abort with ^G)
1> ls().
complex.c complex5.beam complex5.erl complex5.erl~
exampledrv port_driver.c port_driver.c~
ok
2> erl_ddll:load_driver(".", "exampledrv").
{error,{open_error,-10}}
3> erl_ddll:format_error({open_error, -10}).
"cannot open shared object file: No such file or directory"
Кто-нибудь знает в чём может быть проблема?