`
mryufeng
  • 浏览: 982700 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

erl_nif 扩展erlang的另外一种方法

阅读更多
我们知道扩展erl有2种方法, driver和port. 这2个方法效率都低,因为都要经过 port机制,对于简单的模块,这个开销有时候是不可接受的。这时候nif来救助了。今天发布的R13B03已经支持了,虽然是实验性质的。erl_nif的代表API functions for an Erlang NIF library。 参考文档:
erl_nif.html 和 erlang.html#erlang:load_nif-2 以及 reference_manual/code_loading.html#id2278318

我们来用nif写个最简单的hello, 来展现nif的威力和简单性。
不啰嗦,直接上代码:

root@nd-desktop:~/niftest# cat niftest.c
/* niftest.c */
#include "erl_nif.h"
static ERL_NIF_TERM hello(ErlNifEnv* env)
{
    return enif_make_string(env, "Hello world!");
}
static ErlNifFunc nif_funcs[] =
{
    {"hello", 0, hello}
};
ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL)

root@nd-desktop:~/niftest# cat niftest.erl
-module(niftest).
%-on_load(init/0).
-export([init/0, hello/0]).
init() ->
      ok=erlang:load_nif("./niftest", 0), true.
hello() ->
      "NIF library not loaded".

编译:
root@nd-desktop:~/niftest# gcc -fPIC -shared -o niftest.so niftest.c -I   /usr/local/lib/erlang/usr/include  #你的erl_nif.h路径

运行:
root@nd-desktop:~/niftest# erl
Erlang R13B03 (erts-5.7.4) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4  (abort with ^G)
1> c(niftest).
{ok,niftest}
2> niftest:hello().
"NIF library not loaded"
3> niftest:init().
ok
4> niftest:hello().
"Hello world!"
5>

现在重新修改下 niftest.erl 把on_load的注释去掉
利用模块的自动加载机制来自动初始化。


root@nd-desktop:~/niftest# erl
Erlang R13B03 (erts-5.7.4) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4  (abort with ^G)
1> c(niftest).
{ok,niftest}
2> niftest:hello().
"Hello world!"
3>

Note: Nbif参与erlang的公平调度, 你调用了nif函数,VM不保证马上调用你的函数实现,而是要到VM认为合适的时候才调用。

综述: nbif很简单,而且高效。
分享到:
评论
7 楼 xumingyong 2010-01-31  
新问题:如何才能让.so库的内容循环传递到erlang呢? 比如说我有一个100W行的文件,每次在库中读一行就返回给erlang。这个怎么实现?如果用reload或update方式传递,每一次都需要打开文件,而且总是读取第一行,怎么办。。。
6 楼 mryufeng 2009-11-27  
Nbif参与erlang的公平调度, 你调用了nif函数,VM不保证马上调用你的函数实现,而是要到VM认为合适的时候才调用。
5 楼 mryufeng 2009-11-27  
port/driver修改实现功能没问题,但是有3个巨大的差别:

1. Nif的函数可以把旧的模块的函数覆盖掉。比如说 旧的M:F有问题, 我可以写个NIF把这个有问题的函数代替掉。而port不能。

2. Nif函数可以直接调用, Port系列的都要通过port_XXXX接口来完成。。

3. Nif调用路径短,效率高。
4 楼 cryolite 2009-11-27  
mryufeng 写道
这个没有任何的数据copy来copy去, 就是简单的调用c函数,有专门的opcode对应的,是极品的快的。。。

是说Erlang内的数据和Port/Driver的数据实际上是同一块吗,那在Port/Driver中用C修改后会怎样
3 楼 cryolite 2009-11-27  
whrllm 写道
好东西啊,太棒了,谢谢老大把不断挖掘出来的东西共享给我们.

有个问题请教一下,用这东西,是不是可以减少通过port的数据被copy来copy去啊?谢谢


这里提供了一个hack的办法,直接读取erlang内的数据

不过应该不能修改
2 楼 mryufeng 2009-11-27  
这个没有任何的数据copy来copy去, 就是简单的调用c函数,有专门的opcode对应的,是极品的快的。。。
1 楼 whrllm 2009-11-26  
好东西啊,太棒了,谢谢老大把不断挖掘出来的东西共享给我们.

有个问题请教一下,用这东西,是不是可以减少通过port的数据被copy来copy去啊?谢谢

相关推荐

    erl_nif 扩展erlang的另外一种方法

    在“erl_nif 扩展erlang的另外一种方法.pdf”中,可能详细介绍了以上各步骤的实践指南,包括示例代码和最佳实践。而“更多erlang资料下载.txt”则可能提供了进一步学习Erlang和`erl_nif`的资源链接。 通过`erl_nif`...

    erl_nif_rustler_过程宏写法

    总的来说,`erl_nif_rustler`提供了一种更安全、更方便的方式来编写Erlang NIF,避免了直接使用C/C++的复杂性,同时保持了性能优势。通过理解`rustler_macro`的过程宏和Erlang NIF的生命周期,开发者可以轻松地将...

    erlang版本的protobuf(erl_protobuffs)

    `erl_protobuffs`为Erlang开发者提供了一种高效的protobuf实现,增强了Erlang系统与外部世界的数据交换能力。通过其优化的编码和解码过程,以及对Erlang特性的良好适应,它在处理大量数据时表现出色,是构建高性能、...

    erlang-sd_notify-1.0-2.el7.x86_64.rpm

    erlang-sd_notify-1.0-2.el7.x86_64.rpm

    erlang nif test

    Erlang NIF(Native Implemented Functions)是Erlang虚拟机提供的一种机制,允许开发者用C语言或者其他低级语言编写性能关键部分的代码,并在Erlang系统中无缝调用。这种方式可以充分利用C语言的高效性,同时保持...

    rustler编写erlang nif

    在Erlang生态系统中,Native Implemented Functions (NIFs) 是一种机制,允许开发者用其他语言(如C、C++或Rust)编写性能关键部分的代码,然后在Erlang虚拟机(VM)中调用。Rustler是一个库,专门用于简化使用Rust...

    dirty_scheduler:R17.3 +的Erlang脏调度程序示例

    dirty_scheduler 不要忘记使用“ --enable-dirty-schedulers”... 从Erlang 17.03开始,enif_schedule_dirty_nif,enif_schedule_dirty_nif_finalizer和enif_dirty_nif_finalizer被删除(erl_nif.h)。 更多信息: :

    erlang-rust-nif:在 Rust 中实现的 Erlang NIF 示例

    Rust 中的 Erlang NIF 这是一个如何在 Rust 中实现 NIF 的示例。 它对我有用,也可能对你有用,但如果它吃掉了你的作业,请不要生气。 虽然这将是可行的写现实世界的代码下面这个例子,因为整个erl_nif.h接口可用...

    looking_glass:ErlangElixirBEAM分析器工具

    它被实现为erl_tracer NIF,因此需要Erlang / OTP 22.0或更高版本。 Looking Glass的目的是提供一种非常有效的工具,可在开发和生产环境中使用,并且即使在繁忙的系统上也能够长时间运行。在线文件离线文件仍然在线...

    re2:RE2正则表达式库的Erlang NIF绑定

    RE2正则表达式库的Erlang NIF绑定 使用re2 考虑到RE2的差异,该库的API尽可能遵循标准的Erlang / OTP re API。 $ erl 1> re2:run("Bar-foo-Baz", "FoO", [caseless]). {match,[<<"foo">>]} 2> re2:replace(...

    ErlSybase:用于 erlang 的 Sybase nif 驱动程序

    用于 erlang 的 Sybase nif 驱动程序从重写 用法 0.运行二郎erl ebin/ deps/*/ebin % %Start driver 1 > sybdrv : start ([]) % %Execute query with params 2 > sybdrv : execQueryWithArgs ( testdb , " select ...

    自己写一个tcp 通用服务器

    1. `gen_server`行为:Erlang的`gen_server`行为提供了一种标准方式来实现服务器进程,它包含了一系列的回调函数,如`init/1`(初始化)、`handle_call/3`(处理同步调用)、`handle_cast/2`(处理异步消息)和`...

    elixir-ffi:Elixir的外部功能接口(FFI)

    - 使用Erlang的`erl_nif`调试工具,如`enif_inspect`,来检查NIF的状态。 - 在Elixir测试中,可以模拟NIF失败的情况,确保错误处理逻辑正确。 总结起来,Elixir的FFI是通过NIFs实现的,它允许Elixir代码与C语言库...

    alpine-erlang-builder:带有最新Erlang版本的最新Alpine映像,用于分阶段构建

    当然例外是,如果您的应用程序具有需要本地编译工具链的NIF,但这是用户的一项练习。 尚未做出任何努力来使该映像适合在非特权环境中运行。 存储库所有者对由于不正确的使用或安全实践造成的任何损失不承担任何...

Global site tag (gtag.js) - Google Analytics