ネイティブメソッドとライブラリの実装
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/");