How to call a method in DLL in a Java program

随声附和 提交于 2019-12-28 08:11:25

问题


I am trying to call a method in a DLL using JNA. So far have loaded the DLL using

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

This dll contaings a method that I need to access. How can I execute the method present in DLL in my Java file. Do I create an object or something of the DLL and then get the method name after the dot operator.


回答1:


From the 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);

    }
}



回答2:


Loading the DLL is only the easiest step.

As it is not really trivial to call a method of a DLL from Java this answer is only a summary of hints what you have to do to call a function from a DLL. The whole story would fill a book. And in fact there are several books about JNI (Java Native Interface).

To call a function in a native library you have to declare a method in your java class as native with the java keyword native. The declaration of this method must not have a body.

The name of the function exported from your DLL must match the following pattern: Java_classname_methodname where classname is the name of the class where you declared the native method methodname.

For example if you declare a native method private native void sayHello() in your class MyClass the name of the DLL's function would be: Java_MyClass_sayHello

Also keep in mind that the function must be exported from the DLL with the correct calling conventions JNIEXPORT and JNICALL which are defined in the header file jni.h that comes with your JDK (see include folder)

Every function of a DLL to be called from Java also must have two "hidden" arguments as first parameters (JNIEnv *env, jobject obj). env is a pointer to the calling JVM which allows you callback into the JVM and obj is the object from which the method was called.

So the whole definition of the DLL's method in our example would be: JNIEXPORT void JNICALL Java_MyClass_sayHello(JNIEnv *, jobject);

Due to these restrictions of JNI a DLL called from your code must be specifially made for your code. To use an arbitrary DLL from Java you usually have to create an adapting DLL with the conventions of JNI that itself loads the "target" DLL and calls the required functions.

To generate the correct headers for your adapter DLL you can use the tool javah shipped with the JDK. This tool will generate the headers to be implemented from your Java code.

For further information the documentation of JNI will cover all questions about interaction with the JVM from native code. http://docs.oracle.com/javase/7/docs/technotes/guides/jni/



来源:https://stackoverflow.com/questions/25454697/how-to-call-a-method-in-dll-in-a-java-program

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!