首先引用余老大的话:
“我们知道扩展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”
最近本人在游戏开发中需要中道erl_nif的模块+C来处理lua脚本,在一段时间的学习之后,也算是有点点的理解,
不理了,开始编写代码,首先要解决其中的一些数值转换问题,于是有了下面的代码:
niftest.erl
-module(niftest).
-define(BABA, 12).
-export([init/0, hello/1,getNum/2,test/0]).
init() ->
ok=erlang:load_nif("./test", 0).
test() ->
Num = 12 + 13,
Score = hello(Num),
Ab = Score + 21,
io:format("the result:~p\n", [Ab]).
hello(Num) ->
io:format("NIF library not loaded:~p\n", Num).
getNum(_,_) ->
erlang:error(function_clause).
test.c
#include "erl_nif.h"
static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM get_number(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
unsigned long val;
int x = 1234;
int sd;
ERL_NIF_TERM re = enif_make_int(env, x);
if (!enif_get_ulong(env, argv[0], &val))
{
printf("ERROR\n");
return enif_make_badarg(env);
}
else
{
printf("%d\n", val*2);
}
printf("%d,%d\n", re,x);
enif_get_int(env, re, &sd);
printf("%d\n", sd);
return re;
}
static ERL_NIF_TERM get_number(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
int x = 99 ;
int m;
int n;
ERL_NIF_TERM result;
//char buf[10] = "abcdesg";
//Z = a + b;
// Z = luaadd(a, b);
enif_get_int(env, argv[0], &m);
enif_get_int(env, argv[1], &n);
printf("%d, %d\n", argv[0], m);
printf("%d, %d\n", argv[1], n);
x = m + n;
printf("the result:%d\n", x);
result = enif_make_int(env, x);
return result;
// return enif_make_string(env, "HERE IS OK", ERL_NIF_LATIN1);
}
static ErlNifFunc nif_funcs[] ={
{"hello", 1, hello},
{"getNum", 2, get_number}
};
ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL)
函数开始是写成static ERL_NIF_TERM get_number(ErlNifEnv* env, ERL_NIF_TERM a, ERL_NIF_TERM a,)的,
结果每次调用的时候,都会提示
3> niftest:test().
OK
ERROR
** exception error: bad argument
in function niftest:get_number/2
called as niftest:get_number(25,24)
in call from niftest:getNum/2
错误,
后来改成static ERL_NIF_TERM get_number(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
重新执行,OK得咗
2> niftest:getNum(12,32).
207, 12
527, 32
the result:44
44
......至于错误原因,应该是参数传递的错误,在C中没有定义匹配的宏变量或者函数原型,不知道我的理解对不对,希望高手指点!