1

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

/tmp/ccQ0GroH.o:example1_lid.c:(.text+0xe): undefined reference to driver_alloc' /tmp/ccQ0GroH.o:example1_lid.c:(.text+0x2f): undefined reference todriver_free' /tmp/ccQ0GroH.o:example1_lid.c:(.text+0xb0): undefined reference to '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;
}
4

1 回答 1

2

您的代码意味着您正在尝试构建链接的驱动程序。此类驱动程序应编译为记录的共享库。如果使用 gcc,则需要通过-sharedand -fpic。您从链接器收到未定义的引用错误这一事实表明您没有尝试构建共享库。

这里至少还有两个额外的问题:

  1. 你书中的例子已经过时了。如果您使用的是相同版本的 Erlang,这很好。如果您使用的是最新版本,则应参考文档。特别是,您的ErlDrvEntry结构太小,因为它现在包含许多其他字段。

  2. DRIVER_INIT如注释中所述,宏必须采用与 driver_entry 中的名称匹配的参数。然而,代码中的情况并非如此:名称是"example1_drv"while 调用宏时使用example_drv.

此外,driver_free现在 (?) 需要void*并且演员阵容是多余的。

于 2013-10-10T20:30:52.793 回答