Search code examples
javac++c

Calling unmanaged C\C++ DLL methods from Java?


I've been looking at a lot of examples on how to call unmanaged DLL methods from Java using JNI but none of them show the actual calling of the DLL methods. All the examples I've seen just print "Hello World" or add 2 numbers together. Here is some code to show what I'm talking about.

public class NativeClassWrapper {

    public static native void userLogin(int id, char[] username, char[] password);
    
    static {
        System.loadLibrary("User.dll");
    }

    public static void main(String[] args) {

        userLogin(100000, "user123\0".toCharArray(), "password123\0".toCharArray()); 
    }
}
// javac -h NativeClassWrapper.java generate C header

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class NativeClassWrapper */

#ifndef _Included_NativeClassWrapper
#define _Included_NativeClassWrapper
#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jboolean JNICALL Java_dll_call_NativeClassWrapper_userLogin
  (JNIEnv *, jobject, jint, jcharArray, jcharArray);

#ifdef __cplusplus
}
#endif
#endif

At this point I am lost as to how I actually call my 12yr old unmanaged C/C++ DLL method. Do I have to create a whole new duplicate copy of the CPP class file and rename all the methods to match the methods names that were generated by JNI and create a whole new DLL? In C# I didn't have to do anything like that hence my question.

TIA


Solution

  • Yes, when using JNI, you have to wrap those methods in new methods written in C/C++ which abide by the calling conventions required by JNI and perform a lot of additional bureaucratic stuff, for example pinning objects in memory so that the garbage collector will not move them around while your core C/C++ code is trying to access them.

    Have you looked at JNA instead of JNI? It might make things easier.

    (Or what Hovercraft Full of Eels suggests in a comment, it is probably more fresh than JNA.)