.小麥.
一個只喜歡小白兔的大灰狼..

首先引用余老大的话:

“我们知道扩展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中没有定义匹配的宏变量或者函数原型,不知道我的理解对不对,希望高手指点!

posted on 2010-05-24 17:05  酒猫  阅读(1024)  评论(0编辑  收藏  举报