erlang各种有用的函数包括一些有用nif封装,还有一些性能测试case。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

90 lines
2.8 KiB

#include "erl_nif.h"
#define A_OK(env) enif_make_atom(env, "ok")
#define assert_badarg(S, Env) if (! S) { return enif_make_badarg(env); }
static ErlNifResourceType* array_handle = NULL;
static void array_handle_cleanup(ErlNifEnv* env, void* arg) {}
static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
{
ErlNifResourceFlags flags = ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER;
array_handle = enif_open_resource_type(env, "native_array_nif", "array_handle",
&array_handle_cleanup, flags, 0);
// 用于存储指针的数组, 最多1000个array
*priv = enif_alloc(1000 * sizeof(void*));
return 0;
}
static void unload(ErlNifEnv* env, void* priv)
{
enif_free(priv);
}
static ERL_NIF_TERM new_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
// 取参数
int refindex;
assert_badarg(enif_get_int(env, argv[0], &refindex), env);
// 取参数length
unsigned long length;
assert_badarg(enif_get_ulong(env, argv[1], &length), env);
// 分配内存
// unsigned char* ref = enif_alloc_resource(array_handle, length);
unsigned char* ref = enif_alloc(length);
// 保存指针
*((unsigned char**)enif_priv_data(env) + refindex) = ref;
return A_OK(env);
}
static ERL_NIF_TERM get_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
// 取参数ref
int refindex;
assert_badarg(enif_get_int(env, argv[0], &refindex), env);
unsigned char* ref = *((unsigned char**)enif_priv_data(env) + refindex);
assert_badarg(ref, env);
// 取参数offset
unsigned long offset;
assert_badarg(enif_get_ulong(env, argv[1], &offset), env);
return enif_make_int(env, (int)(*(ref + offset - 1)));
}
static ERL_NIF_TERM put_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
// 取参数ref
int refindex;
assert_badarg(enif_get_int(env, argv[0], &refindex), env);
unsigned char* ref = *((unsigned char**)enif_priv_data(env) + refindex);
// 取参数offset
unsigned long offset;
assert_badarg(enif_get_ulong(env, argv[1], &offset), env);
// 取参数newval
unsigned int newval;
assert_badarg(enif_get_uint(env, argv[2], &newval), env);
// 赋值
*(ref + offset - 1) = (unsigned char)newval;
return A_OK(env);
}
static ERL_NIF_TERM delete_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
// 取参数ref
int refindex;
assert_badarg(enif_get_int(env, argv[0], &refindex), env);
unsigned char* ref = *((unsigned char**)enif_priv_data(env) + refindex);
//enif_release_resource(ref);
enif_free(ref);
return A_OK(env);
}
static ErlNifFunc nif_funcs[] = {
{"new", 2, new_nif},
{"get", 2, get_nif},
{"put", 3, put_nif},
{"delete", 1, delete_nif},
};
ERL_NIF_INIT(native_array, nif_funcs, &load, NULL, NULL, &unload)