给erlang增加自定义模块 ---- C Port Driver
来源:互联网 发布:众泰知豆和吉利知豆 编辑:程序博客网 时间:2024/05/01 21:54
转载:http://kasicass.blog.163.com/blog/static/39561920107264842832/
从官方抄过来的例子,代码流,并讲解需要注意的地方。
http://www.erlang.org/doc/tutorial/c_portdriver.htmlerlang 把自定义模块叫做 driver。
自定义模块与 erlang process 在同一进程:(速度快)
erl proc <----> port <----> YourMod
不同进程:(安全)
erl proc <-----> port <--- pipe ---> YourMod
--------------------------------------------------------------------
%% 实现一个模块,把 Port 的访问封装下
-module(complex5).
-export([start/1, stop/0, init/1]).
-export([foo/1, bar/1]).
start(SharedLib) ->
case erl_ddll:load_driver(".", SharedLib) of
ok -> ok;
{error, already_loaded} -> ok;
{error, Desc} ->
io:format("~p~n", [Desc]),
exit({error, could_not_load_driver})
end,
spawn(?MODULE, init, [SharedLib]).
init(SharedLib) ->
register(complex, self()),
Port = open_port({spawn, SharedLib}, []),
loop(Port).
stop() ->
complex ! stop.
loop(Port) ->
receive
{call, Caller, Msg} ->
Port ! {self(), {command, encode(Msg)}},
receive
{Port, {data, Data}} ->
Caller ! {complex, decode(Data)}
end,
loop(Port)
end.
encode({foo, X}) -> [1, X];
encode({bar, Y}) -> [2, Y].
decode([Int]) -> Int.
foo(X) ->
call_port({foo, X}).
bar(Y) ->
call_port({bar, Y}).
call_port(Msg) ->
complex ! {call, self(), Msg},
receive
{complex, Result} ->
Result
end.
--------------------------------------------------------------------
#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 = arg + 1;
else if ( fn == 2 )
res = arg * 2;
driver_output(d->port, &res, 1);
}
ErlDrvEntry example_driver_entry = {
NULL,
example_drv_start,
example_drv_stop,
example_drv_output,
NULL,
NULL,
"exampledrv",
NULL,
NULL,
NULL,
NULL
};
DRIVER_INIT(exampledrv) // 注意:这里的名字 exampledrv,要和上面 example_driver_entry 中的 "exampledrv" 名字一样
{
return &example_driver_entry;
}
--------------------------------------------------------------------
gcc -o exampledrv.so -I/usr/local/lib/erlang/usr/include/ -fpic -shared port_driver.c
--------------------------------------------------------------------
1> c(complex5).
{ok,complex5}
2> complex5:start("exampledrv").
<0.38.0>
3> complex5:foo(10).
11
4> complex5:bar(20).
40
--------------------------------------------------------------------
我这里演示的是 同一进程 的情况。
需要注意的是,erl_ddll:load_driver() 的模块名,是不包含 .so 后缀的,但实际的动态库文件需要 .so 后缀,否则返回 {error, {open_error, -11}}。
而且,模块名 exampledrv 要与动态库文件名一致,否则返回:bad_driver_name
0 0
- 给erlang增加自定义模块 ---- C Port Driver
- Erlang port driver工作原理
- 给skynet增加websocket模块
- 给golang增加websocket模块
- 给skynet增加websocket模块
- Erlang Port性能评测
- Erlang Port 小心换行
- 如何给内核增加yaffs2模块
- linux 给没有Rewrite模块的Apache增加Rewrite模块
- 给IE浏览器增加自定义右键菜单
- Android-给自定义相机增加贴纸
- Erlang和Port通信数据格式
- Erlang port巧用环境变量
- [Erlang]port(gen_tcp)如何并行?
- 解决linux下erlang关闭port同时也关掉与其连接的c语言进程
- 进一步探究linux下erlang关闭port同时也关掉与其连接的c语言进程
- 解决linux下erlang关闭port同时也关掉与其连接的c语言进程
- Android camera sensor driver port
- Ubuntu 12.04中文输入法的安装
- fbo
- CodeIgniter中的增删改查操作
- 移动端Web开发
- 11G RAC 虚拟机安装(五)
- 给erlang增加自定义模块 ---- C Port Driver
- HAIP Drops Route and RAC Database/ASM Instances Evicts (文档 ID 1554551.1)
- hadoop简介
- 数据库多表连接查询
- linux网络编程之TCP/IP基础(五):分析一帧基于UDP的TFTP协议帧
- sybase IQ(15.2)中的常用函数和存储过程(3)
- zoj 3761 Easy billiards 并查集+dfs
- MySQL 模拟PostgreSQL generate_series 表函数
- lua5.1.4中实现自定义require的loader函数