Подтвердить что ты не робот

Как вызвать метод в DLL в Java-программе

Я пытаюсь вызвать метод в DLL, используя JNA. До сих пор загрузили DLL, используя

Runtime.getRuntime().load("myworkspace/test.dll");

Эта dll содержит метод, к которому мне нужно обратиться. Как я могу выполнить метод, присутствующий в DLL в моем файле Java. Создать объект или что-то из DLL, а затем получить имя метода после оператора точки.

4b9b3361

Ответ 1

Из источника:

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 possible to check the platform on which program runs, for example purposes we assume that there a linux port of the library (it 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);

    }
}

Ответ 2

Загрузка DLL - это самый простой шаг.

Как нетривиально вызывать метод DLL из Java, этот ответ - всего лишь сводка подсказок о том, что вам нужно сделать, чтобы вызвать функцию из DLL. Вся история заполнила бы книгу. И на самом деле есть несколько книг о JNI (Java Native Interface).

Чтобы вызвать функцию в собственной библиотеке, вы должны объявить метод в своем классе java как native с ключевым словом java native. Объявление этого метода не должно иметь тела.

Имя функции, экспортированной из вашей DLL, должно соответствовать следующему шаблону: Java_classname_methodname где classname - это имя класса, в котором вы объявили собственный метод methodname.

Например, если вы объявляете собственный метод private native void sayHello() в своем классе MyClass, имя функции DLL будет: Java_MyClass_sayHello

Также имейте в виду, что функция должна быть экспортирована из DLL с правильными соглашениями о вызовах JNIEXPORT и JNICALL, которые определены в файле заголовка jni.h, который поставляется вместе с вашим JDK (см. папку include)

Каждая функция DLL, которая должна быть вызвана из Java, также должна иметь два "скрытых" аргумента в качестве первых параметров (JNIEnv *env, jobject obj). env - это указатель на вызывающий JVM, который позволяет вам обратный вызов в JVM, а obj - это объект, из которого был вызван метод.

Таким образом, все определение метода DLL в нашем примере будет: JNIEXPORT void JNICALL Java_MyClass_sayHello(JNIEnv *, jobject);

Из-за этих ограничений JNI DLL, вызванная из вашего кода, должна быть специально разработана для вашего кода. Чтобы использовать произвольную DLL из Java, вам обычно нужно создать адаптивную DLL с соглашениями JNI, которая сама загружает "целевую" DLL и вызывает необходимые функции.

Чтобы создать правильные заголовки для вашей DLL-адаптера, вы можете использовать инструмент javah, поставляемый с JDK. Этот инструмент будет генерировать заголовки, которые будут реализованы из вашего Java-кода.

Для получения дополнительной информации документация JNI будет охватывать все вопросы о взаимодействии с JVM из собственного кода. http://docs.oracle.com/javase/7/docs/technotes/guides/jni/