LINUX.ORG.RU

Port driver в Erlang

 


0

1

Пробую способы коннекта 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"

Кто-нибудь знает в чём может быть проблема?

★★★★★

Ответ на: комментарий от cnupm

tnx действительно в этом была причина.

Norgat ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.