ツールキット
この歪みを作成するために、Windows、Oracle JDK、Yasm(マクロなし)、Microsoft Visual Studio 2010のリンカーを使用しました。必要に応じて、これらのコンポーネントをお気に入りに置き換えることは難しくありません。非標準の機能は使用しないようにしました。
JNIを使用する
まず、将来の.dllの関数が呼び出されるJavaのクラスを作成しましょう。
public class TestJNI { native static int sum(int x, int y); // sum public static void main(String[] args) { System.loadLibrary("mydll"); // mydll.dll System.out.println(sum(2, 3)); // } }
Javaでの名前のマングリング
ここで、Javaマシンがライブラリで見つけると予想される関数名を見つける必要があります。 これには、JDKのjavahプログラムを使用します。
javac TestJNI.java
javah TestJNI
これにより、C ++ヘッダーが生成されます。
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class TestJNI */ #ifndef _Included_TestJNI #define _Included_TestJNI #ifdef __cplusplus extern "C" { #endif /* * Class: TestJNI * Method: sum * Signature: (II)I */ JNIEXPORT jint JNICALL Java_TestJNI_sum (JNIEnv *, jclass, jint, jint); #ifdef __cplusplus } #endif #endif
ここに含まれる情報は、主にC ++でライブラリをさらに記述するために必要ですが、関数シグネチャのみに関心があります。
JNIEXPORT jint JNICALL Java_TestJNI_sum (JNIEnv *, jclass, jint, jint);
dllでは、関数の名前はJNICALL Java_TestJNI_sumで、4つのパラメーターを取る必要があります。 最も単純な関数の場合、最初の2つは必要ありません。 ご想像のとおり、JNIEXPORTなどのあらゆる種類の奇妙なデータ型は、JDKの一部であるjni.hファイルで宣言されています。
アセンブラー
ライブラリを書きましょう:
;mydll.asm section .text global Java_TestJNI_sum Java_TestJNI_sum: mov eax, [esp + 12] ; 2 add eax, [esp + 16] ret 16 end
;mydll.def LIBRARY mydll EXPORTS Java_TestJNI_sum
コンパイルとリンク:
yasm -f win32 mydll.asm
link /SUBSYSTEM:windows /DLL /NOENTRY /DEF:mydll.def mydll.obj
出力では、.dllファイルを取得します。これをJavaコードに転送する必要があります。
結果
ファイルmydll.dllとTestJNI.classを1つのフォルダーに入れて、何が起こったかを確認します。
>java TestJNI
5
これは勝利です。2つの数字を追加する方法を学びました!
誰かが突然興味を持つようになったら、次のリンクが役立ちます。
- Javaからのアセンブリ言語プログラムの呼び出しは、このテーマに関する非常に優れた英語の詳細な記事です。
- Mapleでの外部呼び出し用のアセンブラーでのdllの作成-Maple用のアセンブラーライブラリの作成。
- Java Native Interface:Programmer's Guide and Specification -JNIに関する厚い本。