ネイティブメソッドとライブラリの実装
CheerpJでのJavaネイティブインターフェース (JNI)
CheerpJを使用すると、通常C/C++や他のAOTコンパイル言語で実装されるJavaの「ネイティブ」メソッドを、Java Native Interface(JNI)を使用するのと同様に、JavaScriptで実装することができます。
これらのメソッドは、Javaコード内でnative
キーワードによって宣言されていることで識別できます。これらの関数はJavaでは実装されておらず、代わりにJavaScriptで実装されます。
cheerpjInit
のnatives
オプションを使用する
cheerpjInit
は、ネイティブメソッドの実装を提供するためのnatives
オブジェクトを受け取ります。このオブジェクトのキーはネイティブメソッドの名前で、値はその実装です:
- キー: 形式は
Java_<fully-qualified-class-name>_<method-name>
の文字列です。例えば、com.foo.Bar
にbaz
というネイティブメソッドがある場合、そのオブジェクトキーはJava_com_foo_Bar_baz
です。 - 値: 最初のパラメーターとして
CJ3Library
オブジェクトを受け取り、続いてメソッドのパラメーターを取る非同期関数です。この関数は値を返すか、値を解決するPromiseを返すことができます。
パラメーターと戻り値は、変換ルールが適用されます。
例
次のJavaクラスを考えてみましょう:
public class Example { public static void main(String[] args) { alert("Hello, world!"); }
public static native void alert(String message);}
alert
の実装を提供するには、cheerpjInit
関数にnatives
オブジェクトのプロパティとして渡します:
await cheerpjInit({ natives: { async Java_Example_alert(lib, str) { window.alert(str); }, },});await cheerpjRunMain("Example", "/app/");
lib
パラメーターはCJ3Library
であり、ライブラリの他のクラスやメソッドにアクセスするために使用できます。
JNI呼び出しのパラメーターと戻り値は、JavaScript型とJava型の間で自動的に変換されます。
共有/動的ライブラリ用のSystem.loadLibrary
の使用
System.loadLibrary(String libname)
は、ネイティブライブラリ(
.so
、.dll
、または.dylib
ファイル)を読み込み、そのメソッドをJavaコードで利用できるようにするJavaメソッドです。ライブラリは、java.library.path
内の各パスからlibname.so
(WindowsとmacOSではそれぞれlibname.dll
またはlibname.dylib
)というファイルを検索することで見つかります。
CheerpJも同様に動作しますが、libname.js
というファイルを探します。このファイルは、前述のnatives
オブジェクトと同じ構造を持つオブジェクトをエクスポートするモジュールである必要があります。
例
public class Example { static { System.loadLibrary("native"); }
public static void main(String[] args) { new Example().alert("Hello, world!"); }
private native void alert(String message);}
export default { async Java_Example_alert(lib, self, message) { window.alert(message); },};
await cheerpjInit({ javaProperties: ["java.library.path=/app/"] });await cheerpjRunMain("Example", "/app/");