1

Erlang ドライバーがどのように機能するかをよりよく理解しようとしており、本の簡単な例から始めましたが、ネイティブの Erlang ドライバー コードを含む C ファイルをコンパイルしようとすると、次のコンパイル エラー メッセージが表示されました。

/tmp/ccQ0GroH.o:example1_lid.c:(.text+0xe): driver_free への未定義の参照driver_alloc' /tmp/ccQ0GroH.o:example1_lid.c:(.text+0x2f): undefined reference to' /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;
}
4

1 に答える 1

2

あなたのコードは、リンクされたドライバーを構築しようとしていることを意味します。このようなドライバは、文書化されているように共有ライブラリとしてコンパイルする必要があります。gcc を使用する場合は、 と を渡す必要が-sharedあり-fpicます。リンカーから未定義の参照エラーが発生しているという事実は、共有ライブラリを構築しようとしていないことを示唆しています。

ここには、少なくとも 2 つの追加の問題があります。

  1. あなたの本の例はかなり時代遅れです。同じバージョンの Erlang を使用している場合は、これで問題ありません。最新のリリースを使用している場合は、ドキュメントを参照してください。特に、ErlDrvEntry他の多くのフィールドが含まれているため、構造が小さすぎます。

  2. DRIVER_INITマクロは、コメントに記載されているように、driver_entry の名前と一致する引数を取る必要があります。ただし、これはコードでは当てはまりません。名前は"example1_drv"、マクロが で呼び出されている間example_drvです。

さらに、driver_free(?) テイクvoid*とキャストは不要になりました。

于 2013-10-10T20:30:52.793 に答える