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

5 years ago
  1. #include "erl_nif.h"
  2. #define A_OK(env) enif_make_atom(env, "ok")
  3. #define assert_badarg(S, Env) if (! S) { return enif_make_badarg(env); }
  4. static ErlNifResourceType* array_handle = NULL;
  5. static void array_handle_cleanup(ErlNifEnv* env, void* arg) {}
  6. static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
  7. {
  8. ErlNifResourceFlags flags = ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER;
  9. array_handle = enif_open_resource_type(env, "native_array_nif", "array_handle",
  10. &array_handle_cleanup, flags, 0);
  11. // 用于存储指针的数组, 最多1000个array
  12. *priv = enif_alloc(1000 * sizeof(void*));
  13. return 0;
  14. }
  15. static void unload(ErlNifEnv* env, void* priv)
  16. {
  17. enif_free(priv);
  18. }
  19. static ERL_NIF_TERM new_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
  20. {
  21. // 取参数
  22. int refindex;
  23. assert_badarg(enif_get_int(env, argv[0], &refindex), env);
  24. // 取参数length
  25. unsigned long length;
  26. assert_badarg(enif_get_ulong(env, argv[1], &length), env);
  27. // 分配内存
  28. // unsigned char* ref = enif_alloc_resource(array_handle, length);
  29. unsigned char* ref = enif_alloc(length);
  30. // 保存指针
  31. *((unsigned char**)enif_priv_data(env) + refindex) = ref;
  32. return A_OK(env);
  33. }
  34. static ERL_NIF_TERM get_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
  35. {
  36. // 取参数ref
  37. int refindex;
  38. assert_badarg(enif_get_int(env, argv[0], &refindex), env);
  39. unsigned char* ref = *((unsigned char**)enif_priv_data(env) + refindex);
  40. assert_badarg(ref, env);
  41. // 取参数offset
  42. unsigned long offset;
  43. assert_badarg(enif_get_ulong(env, argv[1], &offset), env);
  44. return enif_make_int(env, (int)(*(ref + offset - 1)));
  45. }
  46. static ERL_NIF_TERM put_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
  47. {
  48. // 取参数ref
  49. int refindex;
  50. assert_badarg(enif_get_int(env, argv[0], &refindex), env);
  51. unsigned char* ref = *((unsigned char**)enif_priv_data(env) + refindex);
  52. // 取参数offset
  53. unsigned long offset;
  54. assert_badarg(enif_get_ulong(env, argv[1], &offset), env);
  55. // 取参数newval
  56. unsigned int newval;
  57. assert_badarg(enif_get_uint(env, argv[2], &newval), env);
  58. // 赋值
  59. *(ref + offset - 1) = (unsigned char)newval;
  60. return A_OK(env);
  61. }
  62. static ERL_NIF_TERM delete_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
  63. {
  64. // 取参数ref
  65. int refindex;
  66. assert_badarg(enif_get_int(env, argv[0], &refindex), env);
  67. unsigned char* ref = *((unsigned char**)enif_priv_data(env) + refindex);
  68. //enif_release_resource(ref);
  69. enif_free(ref);
  70. return A_OK(env);
  71. }
  72. static ErlNifFunc nif_funcs[] = {
  73. {"new", 2, new_nif},
  74. {"get", 2, get_nif},
  75. {"put", 3, put_nif},
  76. {"delete", 1, delete_nif},
  77. };
  78. ERL_NIF_INIT(native_array, nif_funcs, &load, NULL, NULL, &unload)