2013-10-09 102 views
1

我想更好地理解Erlang驱动程序是如何工作的,我从一本书的一个简单例子开始,但是当我去编译包含本地Erlang驱动程序代码的C文件时,我收到以下编译错误消息:如何编译Erlang驱动程序?

/tmp/ccQ0GroH.o:example1_lid.c:(.text+0xe):未定义参照driver_alloc' /tmp/ccQ0GroH.o:example1_lid.c:(.text+0x2f): undefined reference to driver_free” /tmp/ccQ0GroH.o:example1_lid.c:(.text+0xb0):未定义参考` driver_output'

有人知道为什么会发生这种情况,我该如何解决它? C文件在下面发布供参考。

谢谢。

/* example1_lid.c */ 

#include <stdio.h> 
#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 = twice(arg); 
    } else if (fn == 2) { 
     res = sum(buff[1], buff[2]); 
    } 
    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 
       data to the port */ 
    NULL,    /* F_PTR ready_input, 
          called when input descriptor ready to read*/ 
    NULL,    /* F_PTR ready_output, 
          called when output descriptor ready to write */ 
    "example1_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; 
} 
+0

你能提供你的编译标志吗? – user

回答

1

您的代码意味着您正在尝试构建链接的驱动程序。 这样的驱动程序应该编译为共享库,如documented。如果您使用gcc,则需要通过-shared-fpic。事实上,你从链接器得到一个未定义的引用错误,表明你并没有试图建立一个共享库。

这里有至少另外两个问题:

  1. 的例子在你的书是非常过时。如果你使用相同版本的Erlang,这很好。如果您使用的是最新版本,请参阅the documentation。特别是,您的ErlDrvEntry结构太小,因为它现在包含许多其他字段。

  2. DRIVER_INIT宏必须采用与driver_entry中的名称匹配的参数,如注释中所述。然而,在代码中并不是这样:名称是"example1_drv",而宏是用example_drv调用的。

此外,driver_free现在(?)采用void*和演员是多余的。