Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Elixirの言語バインディング対応する #57

Open
tmori opened this issue Aug 31, 2024 · 19 comments
Open

Elixirの言語バインディング対応する #57

tmori opened this issue Aug 31, 2024 · 19 comments

Comments

@tmori
Copy link
Contributor

tmori commented Aug 31, 2024

コード

ElixirはCからElixir関数をコールバックできないので、プリミティブな箱庭アセットAPIでバインディングすることにした。参考URL

https://github.com/toppers/hakoniwa-core-cpp-client/blob/main/bindings/elixir/hako_asset_elixir_nif.c

これができたら、Elixir言語でコールバックする機構を作る必要がある。先は長い。

cmake

まずは、Macでビルドできるよう試行中。

https://github.com/toppers/hakoniwa-core-cpp-client/blob/main/bindings/elixir/CMakeLists.txt

これを試すには、以下を有効化することでビルドが走る。

#add_subdirectory(elixir)

@tmori
Copy link
Contributor Author

tmori commented Aug 31, 2024

# Erlangのライブラリとリンク
target_link_libraries(
    hako_asset_nif
    ei
    shakoc
)

エラーログ:何をリンクすれば良いかわからない。。こまった。

libhako_asset_nif.dylib
ld: Undefined symbols:
  _enif_get_long, referenced from:
      _nif_hako_asset_notify_simtime in hako_asset_elixir_nif.c.o
  _enif_get_string, referenced from:
      _nif_hako_asset_register in hako_asset_elixir_nif.c.o
      _nif_hako_asset_get_event in hako_asset_elixir_nif.c.o
      _nif_hako_asset_unregister in hako_asset_elixir_nif.c.o
      _nif_hako_asset_notify_simtime in hako_asset_elixir_nif.c.o
  _enif_make_atom, referenced from:
      _nif_hako_asset_init in hako_asset_elixir_nif.c.o
      _nif_hako_asset_register in hako_asset_elixir_nif.c.o
      _nif_hako_asset_unregister in hako_asset_elixir_nif.c.o
      _nif_hako_asset_notify_simtime in hako_asset_elixir_nif.c.o
  _enif_make_badarg, referenced from:
      _nif_hako_asset_register in hako_asset_elixir_nif.c.o
      _nif_hako_asset_get_event in hako_asset_elixir_nif.c.o
      _nif_hako_asset_unregister in hako_asset_elixir_nif.c.o
      _nif_hako_asset_notify_simtime in hako_asset_elixir_nif.c.o
  _enif_make_int, referenced from:
      _nif_hako_asset_get_event in hako_asset_elixir_nif.c.o
  _enif_make_long, referenced from:
      _nif_hako_asset_get_worldtime in hako_asset_elixir_nif.c.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)

@zacky1972
Copy link

zacky1972 commented Aug 31, 2024

ElixirはCからElixir関数をコールバックできない

出来なくはなくて, enif_send を使う方法があります.ただし,使うのはそこそこ難易度高いです.

下記を参考にすると良いです.

https://github.com/zacky1972/nif_send_sample

@zacky1972
Copy link

zacky1972 commented Aug 31, 2024

エラーログ:何をリンクすれば良いかわからない。。こまった。

elixir_makeMakefile ではありますが,前述の下記を参考にすると良いと思います.

https://github.com/zacky1972/nif_send_sample

@zacky1972
Copy link

もしソースコード読んでみてもわからなかったら,随時 Zoom ミーティング応じますよ!

@tmori
Copy link
Contributor Author

tmori commented Aug 31, 2024

エラーログ:何をリンクすれば良いかわからない。。こまった。

elixir_makeMakefile ではありますが,前述の下記を参考にすると良いと思います.

https://github.com/zacky1972/nif_send_sample

ありがとうございます!リンク通りました!

b655793

@tmori
Copy link
Contributor Author

tmori commented Aug 31, 2024

enif_send

ありがとうございます。なるほど、これってプロセス間通信するような気がしました。

箱庭のシミュレーション時間単位でのコールバックになるので、ちょっとオーバーヘッド高そうっすね。。

@tmori
Copy link
Contributor Author

tmori commented Aug 31, 2024

もしソースコード読んでみてもわからなかったら,随時 Zoom ミーティング応じますよ!

ありがとうございます!
基本的なところは理解できた気がします。

まずは基本的なアセットAPIをElixir化していきます!

@tmori
Copy link
Contributor Author

tmori commented Aug 31, 2024

残りのAPI実装完了!

868008c

@zacky1972
Copy link

ありがとうございます。なるほど、これってプロセス間通信するような気がしました。

厳密にはメッセージ・パッシングに基づく軽量プロセス間通信です.MMUをいじったりするわけではありません.

箱庭のシミュレーション時間単位でのコールバックになるので、ちょっとオーバーヘッド高そうっすね。。

軽量プロセスなので,コールバックそのもののオーバーヘッドは高くありません.

ポインタによる共有メモリ参照をしたい場合は,私はまだ使ったことがないのですが, https://www.erlang.org/doc/apps/erts/erl_nif.html#functionality の Resource objects の項目にある関数群を用いることで,出来ます.

@tmori
Copy link
Contributor Author

tmori commented Aug 31, 2024

ありがとうございます。なるほど、これってプロセス間通信するような気がしました。

厳密にはメッセージ・パッシングに基づく軽量プロセス間通信です.MMUをいじったりするわけではありません.

箱庭のシミュレーション時間単位でのコールバックになるので、ちょっとオーバーヘッド高そうっすね。。

軽量プロセスなので,コールバックそのもののオーバーヘッドは高くありません.

ポインタによる共有メモリ参照をしたい場合は,私はまだ使ったことがないのですが, https://www.erlang.org/doc/apps/erts/erl_nif.html#functionality の Resource objects の項目にある関数群を用いることで,出来ます.

おー、そうなんですね。
それなら話は簡単になります。

@tmori
Copy link
Contributor Author

tmori commented Aug 31, 2024

enif_sendでコールバック関数呼び出し実装してビルドは通りましたー。

78f1f14

@tmori
Copy link
Contributor Author

tmori commented Aug 31, 2024

ビルド通って、動くようになりましたが、コールバック関数が呼び出されない。。

0caf1d5

@tmori
Copy link
Contributor Author

tmori commented Aug 31, 2024

ChatGPTに書かせたので、ちゃんと意味を理解しようっと。

@tmori
Copy link
Contributor Author

tmori commented Sep 1, 2024

サンプルコードを追加:

bcf367d

@tmori
Copy link
Contributor Author

tmori commented Sep 1, 2024

うーん、enif_sendはデータ送信して即復帰するだけなのかな?
結果を受け取るまで待ち合わせしたいのだけど、どうするんだろう。。
https://www.erlang.org/doc/apps/erts/erl_nif.html#enif_send

@tmori
Copy link
Contributor Author

tmori commented Sep 1, 2024

色々やってみましたが、どうもダメですね。。

ポーリングベースに戻します。

@zacky1972
Copy link

うーん、enif_sendはデータ送信して即復帰するだけなのかな?

そうです.非同期通信なので,メッセージを送ったら送りっぱなしです.

同期的なプログラミングにするには,Promiseで行うような仕掛けを組むことが必要です.

@tmori
Copy link
Contributor Author

tmori commented Sep 1, 2024

箱庭アセットAPI以外はほぼ出来上がりました。

elixir_project
├── README.md
├── lib
│   ├── hako_api.ex
│   ├── hako_asset.ex
│   ├── hako_conductor.ex
│   └── hako_simevent.ex
├── mix.exs
├── priv
│   └── libhako_asset_nif.so 
├── src
│   ├── CMakeLists.txt
│   └── hako_asset_elixir_nif.c
└── test
    ├── hako_conductor_test.exs
    ├── hako_simevent_test.exs
    └── test_helper.exs

@tmori
Copy link
Contributor Author

tmori commented Sep 2, 2024

現時点の状況(9/3)

  • 箱庭APIのElixir実装は一通り完了しましたただし、箱庭PDUデータはバイナリでのI/Oです。
  • 箱庭PDUデータのI/Oテストは未完状態なので、pdu_communicationのサンプルアプリ移植を行なってテスト予定
  • バイナリデータをJSONデータに変換するスクリプトは移植しきれませんでした。
    • こちらについては、C++でJSONテキスト変換するAPI実装を提供予定

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants