4

Erlang でコーディングする予定のアプリの NIF を使用してバイナリを操作するつもりです。NIF の cpp ファイルと erl ファイルへの gist リンクを以下に示します。

[Erl Gist リンク] https://gist.github.com/abhijitiitr/3a5bc97184d6dd32f97b

[C++ Gist リンク] https://gist.github.com/abhijitiitr/24d2b780f2cdacebfb07

基本的に私は簡単なテストをしようとしています。NIF 呼び出し間でバイナリを共有し、連続する NIF 呼び出しでそれらを正常に操作します。

erlang REPL でコードをテストすると、

c(binary_test).
Ref=binary_test:open(<<1>>).
binary_test:increment(Ref,<<3>>).

バイナリは、NIF 呼び出しの間に変更を保存しました。3 番目のコマンドの REPL 出力は次のとおりです。

1
 3
  60
    60
      <<"?">>

<<1>>初期化フェーズでパスしました。なぜに変わったの<<60>>ですか?ここで何が起こっているのか理解できません。誰かがエラーを指摘できますか?

C++ コンパイル命令

clang++ -std=c++11 -stdlib=libc++ -undefined dynamic_lookup -O3 -dynamiclib binary_test.cpp -o binary_test.so -I /usr/local/Cellar/erlang/17.0/lib/erlang/erts-6.0/include/ 

私のMacで。

また、NIF で共有リソースを操作する並行プロセスについても質問したいと思いました。それは可能ですか、それとも単一の Erlang プロセスで NIF にアクセスする必要があるという規則がありますか。

4

2 に答える 2

5

メモリに不正にアクセスしているため、問題が発生しています。BinaryStoreコンストラクターで、に渡された引数リストからバイナリを保存しようとしていますがbinary_test:open/1、NIF 呼び出しが終了するとこれらの引数が解放されるため、これは機能しません。後で使用するには、引数のコピーを保存する必要があります。これを行うには、まずBinaryStoreクラスに新しいメンバーを追加します。

    ErlNifEnv* term_env;

次に、コンストラクターを変更して割り当てterm_env、それを使用して着信用語をコピーします。

    BinaryStore(ERL_NIF_TERM binary)
    {
        term_env = enif_alloc_env();
        binary_term = enif_make_copy(term_env, binary);
    }

binary_termこれにより、環境に割り当てられterm_env、着信用語が環境にコピーされます。また、解放するためのデストラクタも必要ですterm_env:

    ~BinaryStore()
    {
        enif_free_env(term_env);
    }

そして最後に、関数で検査するときterm_envの代わりに渡す必要があります。envbinary_termincrement_binary

    nifpp::get_throws(term_env, binary_term, ibin);

これらの変更を行うと、コードを実行して次の結果が得られます。

1> Ref=binary_test:open(<<1>>).
Reading symbols for shared libraries . done
<<>>
2> binary_test:increment(Ref,<<3>>).
1
 3
  1
   1
    <<4>>

(ちなみに、改行が常に左端の列に戻るように、Erlang エミュレーター内から印刷するとき"\r\n"だけでなく、行末を使用する必要があります。)"\n"

まだ 1 つの問題が残っています。それは、に割り当てられたメモリをリークすることですnew_bin2

NIF の詳細を学ぶための私のアドバイスはnifpp、最初のようなパッケージの使用を避けることです。そうすれば、NIF APIと、メモリの所有権、リソースの割り当てと解放、および引数の変換に関するすべての詳細を学ぶことができます。それらを理解すると、パッケージのようなものを使用することnifppがはるかに簡単になり、実り多いものになります。

于 2014-10-22T13:31:27.260 に答える