Hello Project Panama, on Java17
はじめに
で、 Project Panama (リンク1, リンク2) の機能を利用して、 Java から Rust を呼び出してみました。
当時(Java14)は Project Panama 用にビルドされた JDK を利用する必要がありましたが、 Java17 では incubator ではあるものの JEP 412: Foreign Function & Memory API が標準 JDK に導入された
ので、標準の JDK でも冒頭にリンクしたコード相当のものをビルド、実行できるようになりました(※ 後述の通り jextract コマンド は標準 JDK に含まれていないので別途取得する必要があります)。
API, jextract コマンド引数など、 Java14 当時と結構変わっていましたので、改めて project Panama を使って Hello, world してみたいと思います。
今回の成果物は次のリンク先にあります:
環境
-
Ubuntu 20.04
- 後で Windows10 上でも試してみましたが、こちらも上手く動作しました
-
Java Corretto-17.0.0.35.1
-
jextractBuild 17-panama+3-167 (2021/5/18) -
rustc 1.55.0
作成手順
Rust でダイナミックリンクライブラリ作成
greeter という名前でプロジェクトを作成します。 プロジェクトルートディレクトリで次のコマンドを実行します。
|
|
libc クレートを依存関係に追加します。 また、ダイナミックリンクライブラリを生成するように crate-type に cdylib を設定します。
Cargo.toml
|
|
Rust 側で行う処理を実装します。
src/lib.rs
|
|
ビルドします。
|
|
参考
-
The Cargo Book > 3.2.1. Cargo Targets > The crate-type field
-
The Rustonomicon > 11. Foreign Function Interface > Calling Rust code from C
ダイナミックリンクライブラリの C ヘッダ自動生成
上で作成したライブラリのヘッダファイルを自動生成します。
cbindgen コマンドをインストールします。
|
|
プロジェクトルートディレクトリで次のコマンドを実行します。
|
|
上記コマンド実行により bridges/greeter.h ヘッダファイルが生成されます。
bridges/greeter.h
|
|
C ヘッダから Java API 自動生成
jextract コマンドを利用してヘッダファイルから Java API を自動生成します。
jextract コマンドは Project Panama の Early Access Build をダウンロードし展開すると bin ディレクトリ下にあります。
プロジェクトルートディレクトリで次のコマンドを実行します。
/path/to/jextract \
-l greeter \
-d classes \
-t com.example \
./bridges/greeter.h
上記コマンドを実行すると classes ディレクトリ下にクラスファイルが生成されます。
補足/参考
-
上で自動生成した
bridges/greeter.hは、実際には不必要なインクルードを含んでいます。 これを削減し、#include <stddef.h>(size_tを定義しているヘッダファイル) だけにすると、ここで自動生成されるファイルも減ります。 -
jextractコマンドに--sourceオプションを付与すると、.classファイルでなく.javaファイルが生成されます。 -
jextractコマンドの詳細は次のリンク先を参照:-
Using the jextract tool - openjdk/panama-foreign
- 同階層
docディレクトリには他にも参考になるドキュメントあり
- 同階層
-
呼び出し側を Java で実装
jdk.incubator.foreign 機能を用いてメモリ領域を確保し、自動生成した API com.example.greeter_h.greeter() を呼ぶコードを実装します。
src/Main.java
|
|
補足
-
IDE を用いる場合、次のリンク先に IntelliJ の設定方法が説明されています。
-
https://github.com/carldea/panama4newbies/blob/main/README.md
- こちらのリンク、IDE の設定方法だけでなく、 Project Panama 全体の説明もわかりやすいと思います
-
Java コードビルド
上記のコードを JDK17 でビルドするには --add-modules jdk.incubator.foreign オプションを付与する必要があります。
|
|
実行
--enable-native-access=ALL-UNNAMED, --add-modules jdk.incubator.foreign オプションが必要です。
|
|
参考/補足
-
Windows で実行する場合、
LD_LIBRARY_PATHは機能しません。 代わりに、./greeter/target/release/greeter.dllをカレントディレクトリにコピーしてから上のコマンドを実行します。 -
Using the jextract tool > Running the Java code that invokes helloworld