Javaでは、他のプログラミング言語、いわゆる
JNIで実装されたプログラムコードを使用できます。 動的にリンクされたライブラリを記述し、それをJavaコードにロードしてそこから関数を使用し、それをロードしたクラスのネイティブメソッドとして宣言できます。 JNIは、主にC / C ++でマシン依存のアクションを実行するために作成され(また、アプリケーションの速度が重要な部分のパフォーマンスを向上させるため)、アセンブラーでライブラリを作成することを誰も気にしません。
ツールキット
この歪みを作成するために、Windows、Oracle JDK、Yasm(マクロなし)、Microsoft Visual Studio 2010のリンカーを使用しました。必要に応じて、これらのコンポーネントをお気に入りに置き換えることは難しくありません。非標準の機能は使用しないようにしました。
JNIを使用する
まず、将来の.dllの関数が呼び出されるJavaのクラスを作成しましょう。
public class TestJNI { native static int sum(int x, int y);
Javaでの名前のマングリング
ここで、Javaマシンがライブラリで見つけると予想される関数名を見つける必要があります。 これには、JDKのjavahプログラムを使用します。
javac TestJNI.java
javah TestJNI
これにより、C ++ヘッダーが生成されます。
#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つの数字を追加する方法を学びました!
誰かが突然興味を持つようになったら、次のリンクが役立ちます。