Erlang Linked in driver

2009-05-24
Erlang允许其他语言编写的程序以共享库的方式动态连接到Erlang运行时环境里运行,与Erlang Port的方式相似,这种方式称为linked-in driver(内部连接驱动??),是Erlang与其他语言程序交互的最高效的方式,但同时也是最危险的,因为一旦驱动内部出现致命异常,Erlang虚拟机也会崩溃,拖累其他Erlang进程一起挂掉,因此如非必要不推荐使用linked-in driver。

下面是C++编写的driver,具体代码结构解析请参见《Programming Erlang》
#include 
#include "erl_driver.h"
using namespace std;

struct data{
    ErlDrvPort port;
};

//PORT打开时执行
static ErlDrvData start(ErlDrvPort port, char *buff){
    data* d = (data*)driver_alloc(sizeof(data));
    d->port = port;
    return (ErlDrvData)d;
}

//PORT关闭时执行
static void stop(ErlDrvData handle){
    driver_free((char*)handle);
}

//ERLANG发送来信息时执行
static void output(ErlDrvData handle, char *buff, int bufflen){
    cout << buff << endl;
    char rs[] = "ok";
    data* d = (data*)handle;
    driver_output(d->port, rs, 2);
}

ErlDrvEntry driver_entry = {
    NULL,    //F_PTR init N/A
    start,   //L_PTR PORT打开时执行此函数
    stop,    //F_PTR PORT关闭时执行此函数
    output,  //F_PTR ERLANG发来信息时执行
    NULL,    //F_PTR ready_input, called when input descriptor ready to read
    NULL,    //F_PTR ready_output
    "test",  //DRIVER名,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
};

extern "C"{
    DRIVER_INIT(test){
        return &driver_entry;
    }
}
然后用如下命令编译成共享库:
g++ test.cpp -I/usr/local/lib/erlang/usr/include/ -fPIC -shared -o test.so

Erlang里调用这个共享库的代码如下:
-module(test).
-compile(export_all).

start() ->
    ok = erl_ddll:load_driver(".", "test"),
    Port = open_port({spawn, "test"}, [{packet, 2}]),
    Port ! {self(), {command, "woo just a test"}},
    receive
        {Port, {data, Data}} ->
            ok = io:format("[~p/~p] ~p\n", [?MODULE, self(), Data])
    end,
    Port ! {self(), close}.

M-OSCAR | Powered by Blogger | Entries (RSS) | Comments (RSS) | Designed by MB Web Design | XML Coded By Cahayabiru.com