JNAを使用してDLLでメソッドを呼び出そうとしています。これまでにDLL
Runtime.getRuntime().load("myworkspace/test.dll");
このdllには、アクセスする必要があるメソッドが含まれています。 DLL in my Java file。オブジェクトまたは何かを作成しますDLL =そして、ドット演算子の後にメソッド名を取得します。
source から:
package jnahelloworldtest;
import com.Sun.jna.Library;
import com.Sun.jna.Native;
import com.Sun.jna.NativeLong;
import com.Sun.jna.Platform;
import com.Sun.jna.*;
/** Simple example of native library declaration and usage. */
public class Main {
public interface simpleDLL extends Library {
simpleDLL INSTANCE = (simpleDLL) Native.loadLibrary(
(Platform.isWindows() ? "simpleDLL" : "simpleDLLLinuxPort"), simpleDLL.class);
// it's possible to check the platform on which program runs, for example purposes we assume that there's a linux port of the library (it's not attached to the downloadable project)
byte giveVoidPtrGetChar(Pointer param); // char giveVoidPtrGetChar(void* param);
int giveVoidPtrGetInt(Pointer param); //int giveVoidPtrGetInt(void* param);
int giveIntGetInt(int a); // int giveIntGetInt(int a);
void simpleCall(); // void simpleCall();
}
public static void main(String[] args) {
simpleDLL sdll = simpleDLL.INSTANCE;
sdll.simpleCall(); // call of void function
int a = 3;
int result1 = sdll.giveIntGetInt(a); // calling function with int parameter&result
System.out.println("giveIntGetInt("+a+"): " + result1);
String testStr = "ToBeOrNotToBe";
Memory mTest = new Memory(testStr.length()+1); // '+1' remember about extra byte for \0 character!
mTest.setString(0, testStr);
String testReturn = mTest.getString(0); // you can see that String got properly stored in Memory object
System.out.println("String in Memory:"+testReturn);
Memory intMem = new Memory(4); // allocating space
intMem.setInt(0, 666); // setting allocated memory to an integer
Pointer intPointer = intMem.getPointer(0);
int int1 = sdll.giveVoidPtrGetInt(Pointer.NULL); // passing null, getting default result
System.out.println("giveVoidPtrGetInt(null):" + int1);
int int2 = sdll.giveVoidPtrGetInt(intMem); // passing int stored in Memory object, getting it back
//int int2 = sdll.giveVoidPtrGetInt(intPointer); causes JVM crash, use memory object directly!
System.out.println("giveVoidPtrGetInt(666):" + int2);
byte char1 = sdll.giveVoidPtrGetChar(Pointer.NULL); // passing null, getting default result
byte char2 = sdll.giveVoidPtrGetChar(mTest); // passing string stored in Memory object, getting first letter
System.out.println("giveVoidPtrGetChar(null):" + (char)char1);
System.out.println("giveVoidPtrGetChar('ToBeOrNotToBe'):" + (char)char2);
}
}
DLLのロードは、最も簡単な手順です。
DLLからJavaのメソッドを呼び出すのは本当に簡単ではないので、この回答は、DLLから関数を呼び出すために何をしなければならないかというヒントの要約にすぎません。物語全体が本になります。そして実際、JNI(Java Native Interface)についての本がいくつかあります。
ネイティブライブラリの関数を呼び出すには、Javaキーワードnative
を使用して、Javaクラスのメソッドをネイティブとして宣言する必要があります。このメソッドの宣言には本体を含めることはできません。
DLLからエクスポートされる関数の名前は、次のパターンと一致する必要があります。Java_classname_methodname
ここで、classname
は、ネイティブメソッドmethodname
を宣言したクラスの名前です。
たとえば、クラスMyClassでネイティブメソッドprivate native void sayHello()
を宣言する場合、DLLの関数の名前は次のようになります。Java_MyClass_sayHello
また、JDKに付属のヘッダーファイルjni.hで定義されている正しい呼び出し規約JNIEXPORTおよびJNICALLを使用して、関数をDLLからエクスポートする必要があることに注意してください(includeフォルダーを参照)
DLLから呼び出されるJavaのすべての関数にも、最初のパラメーター(JNIEnv *env, jobject obj)
として2つの「隠された」引数が必要です。 env
は、JVMへのコールバックを許可する呼び出し側JVMへのポインターであり、obj
はメソッドの呼び出し元のオブジェクトです。
したがって、この例のDLLのメソッドの定義全体は次のようになります。JNIEXPORT void JNICALL Java_MyClass_sayHello(JNIEnv *, jobject);
これらのJNIの制限のため、コードから呼び出されるDLLは、コード用に特別に作成する必要があります。 DLLから任意のJavaを使用するには、通常、それ自体が「ターゲット」DLLをロードして必要な関数を呼び出すJNIの規則で適応DLLを作成する必要があります。
アダプタDLLの正しいヘッダーを生成するには、JDKに付属のツールjavahを使用できます。このツールは、Javaコードから実装されるヘッダーを生成します。
詳細については、JNIのドキュメントに、ネイティブコードからJVMとの対話に関するすべての質問が記載されています。 http://docs.Oracle.com/javase/7/docs/technotes/guides/jni/