Pull to refresh

Comments 7

Здорово, но по-моему, по официальной документации написать ниф будет проще, чем по вашей статье.

И вообще, так
static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) {
  ex_pigpio_priv* data = enif_alloc(sizeof(ex_pigpio_priv));
  //...
  data->atom_ok = enif_make_atom(env, "ok");
  data->atom_error = enif_make_atom(env, "error");


делать нельзя
ErlNifEnv represents an environment that can host Erlang terms. All terms in an environment are valid as long as the environment is valid. ErlNifEnv is an opaque type and pointers to it can only be passed on to API functions. There are two types of environments; process bound and process independent.

A process bound environment is passed as the first argument to all NIFs. All function arguments passed to a NIF will belong to that environment. The return value from a NIF must also be a term belonging to the same environment. In addition a process bound environment contains transient information about the calling Erlang process. The environment is only valid in the thread where it was supplied as argument until the NIF returns. It is thus useless and dangerous to store pointers to process bound environments between NIF calls.
Не могли бы вы поделиться официальной документацией о том, как написать NIF в Elixir? Когда я начал писать мои NIF, я не нашел никакой официальной информации об этом. Заметьте, что цель статьи заключается именно в том, чтобы показать как написать и использовать NIF в Elixir. По этой причине я обратил больше внимания на то, как интегрировать NIF с mix и модулями Elixir.

data->atom_ok = enif_make_atom(env, "ok");

Это можно делать, так как enif_make_atom является не задокументированным исключением из общего правила. Посмотрите тут: erlang.2086793.n4.nabble.com/erl-nif-environment-in-the-load-function-td4674510.html

Normally the lifetime of a term is determined by its environment.
However, atoms are an exception to this rule, which allows you to
prefabricate atoms in static variables.

This exceptions is undocumented but widely used (by myself included in
crypto). There is a small risk that an introduction of atom garbage
collection in some non predictable future release will have to break
this feature.

Однако так как это поведение не задокументировано, я не упомянул эту часть кода в статье.

Не могли бы вы поделиться официальной документацией о том, как написать NIF в Elixir?

Я имел в виду вот эту: www.erlang.org/doc/man/erl_nif.html и www.erlang.org/doc/tutorial/nif.html

Там все-таки логичнее изложено.

enif_make_atom является не задокументированным исключением из общего правила.

Каждый раз, когда вы используете недокументированные возможности, где-то умирает котенок
Там нет никакой информации о том, как использовать NIF в Elixir и компилировать его с помощью mix. Об этом, собственно говоря, и есть статья. Я сам даю ссылку на официальную документацию NIF в Си, так как Си-код не является главной темой статьи. А вот котов я не люблю и повторно говорю, что я никому не рекомендовал имплементировать load, как это сделал я, и я абсолютно ничего не писал об имплементации этой функции.
Си-код не является главной темой статьи
И тем не менее, C-код составляет половину статьи

А вот котов я не люблю и повторно говорю, что я никому не рекомендовал имплементировать load, как это сделал я
Нет, вы не поняли, это я вам указываю на ошибку в вашей библиотеке, которую необходимо исправить.
Кроме того, если вы показываете код в статье, претендующей на обучающий материал, то вы не должны допускать в нем таких ляпов.
UFO just landed and posted this here
Можно ещё избавиться в Makefile-е от необходимости делать erlang eval, если передавать CFLAGS, как аргумент к make:

cfags = ['CFLAGS=', ['-I', :code.root_dir(), '/erts-', :erlang.system_info(:version), '/include']]
System.cmd("make", [cflags, ...
Sign up to leave a comment.

Articles