NIF即是(Native Implemented Function),由c实现的函数。其实即是一些动态库比如So、DLL。。。
nif在erlang的r13b才引进的,是一个比port更简单而且更有效率的方式调用C库。
nif直接链接到erts proc,不用context switch, 所以是非常有效率的,但是也是最不安全的,nif的异常有可能导致
erts 的崩溃。
废话少说,直接上代码:
Erlang:
-module(complex6).
-export([foo/1, bar/1]).
-on_load(init/0).
init() ->
ok = erlang:load_nif("./complex6_nif", 0).
foo(_X) ->
exit(nif_library_not_loaded).
bar(_Y) ->
exit(nif_library_not_loaded).
C:
#include "erl_nif.h"
extern int foo(int x);
extern int bar(int y);
static ERL_NIF_TERM foo_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
int x, ret;
if (!enif_get_int(env, argv[0], &x)) {
return enif_make_badarg(env);
}
ret = foo(x);
return enif_make_int(env, ret);
}
static ERL_NIF_TERM bar_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
int y, ret;
if (!enif_get_int(env, argv[0], &y)) {
return enif_make_badarg(env);
}
ret = bar(y);
return enif_make_int(env, ret);
}
static ErlNifFunc nif_funcs[] = {
{"foo", 1, foo_nif},
{"bar", 1, bar_nif}
};
ERL_NIF_INIT(complex6, nif_funcs, NULL, NULL, NULL, NULL)
编译C->
unix> gcc -o complex6_nif.so -fpic -shared complex.c complex6_nif.c windows> cl -LD -MD -Fe complex6_nif.dll complex.c complex6_nif.c
测试:
> erl Erlang R13B04 (erts-5.7.5) [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false] Eshell V5.7.5 (abort with ^G) 1> c(complex6). {ok,complex6}
3> complex6:foo(3). 4 4> complex6:bar(5). 10 5> complex6:foo("not an integer"). ** exception error: bad argument in function complex6:foo/1 called as comlpex6:foo("not an integer")可以与之前的port实现进行比较。
本文深入探讨了Erlang中用于调用C库的两种方式:NIF(Native Implemented Function)和Port,并通过代码示例展示了如何使用NIF直接链接到ERTS进程,实现高效而安全的库调用。同时,对比了两者在实际应用中的区别,旨在帮助开发者更好地选择合适的库调用策略。
358

被折叠的 条评论
为什么被折叠?



