Calling C++ dll from Java
Solution 1
You need to include the Java class name and path in your native code, for example if your native method was declared in Java as:
public class NativeCode {
public static native boolean CreateSession();
}
and the class path was (for example) com.example.NativeCode
you would declare your method in native as follows:
extern "C"
JNIEXPORT jboolean JNICALL Java_com_example_NativeCode_CreateSession(JniEnv* env, jclass clazz)
{
return JNI_TRUE;
}
All JNI methods have a JNIEnv pointer and class as their first two parameters.
Solution 2
A static native method still needs at least two parameters:
JNIEnv *env
jclass clazz
The function name also has to correspond the the java package structure.
JNIEXPORT jboolean JNICALL Java_com_example_CreateSession(JNIEnv *env, jclass clazz)
Ideally, you would use the javah
tool to create a header file from the java class declaring the native method and then implement the declared function prototypes.
Solution 3
I had a similar problem - an existing C-Codebase which i needed to access from Java. It paid off for me, to get familiar with SWIG, a tool to generate an intermediate C++ DLL (which calls the C-Code), plus Java-Code that is calling into the C++ DLL.
If you have more than just 1 function of the DLL to wrap, it might pay off to check out this tool, otherwise you'd have to get familiar with JNI...
EDIT:
It seems like your DLL is not found by the System.load()
call. You might want to try System.loadLibrary()
, but note that your DLL must then be located in the path denoted by the Java system property java.library.path
.
Also dont pass the full filename in this case, but just the filename without extension.
nickfinity
Updated on July 09, 2022Comments
-
nickfinity almost 2 years
I'm using Java for a small app. It's a rewrite of an existing MFC project. There is an existing dll that I need to change to enable access from Java using JNI. All of this Java stuff is new to me, so I'm having a little trouble and feeling rather dense when I read other forum posts. In the existing dll I have a function like this:
extern "C" __declspec(dllexport) bool Create() { return TRUE; }
Dumb question time. How do I properly set it up to be called by Java?
I tried this:
JNIEXPORT jboolean JNICALL Create() { return TRUE; }
I'm including jni.h and everything compiles fine. However, when I call it from Java I get UnsatisfiedLinkError. I'm calling it from Java using this:
public static native boolean CreateSession(); System.load("D:\\JavaCallTest.dll"); Create();
Could someone kindly push me in the proper direction? I sincerely appreciate any help.
Thanks,
Nick
-
Andy Thomas over 12 years+1 for mentioning that javah should be used to generate the function signatures.
-
nickfinity over 12 yearsThat was it. It seems to be working now. We'll see what kind of issues I run into when I'm not dealing with a simple function like this. I appreciate the help.
-
nickfinity over 12 yearsIt was finding the DLL, but I didn't have my function properly declared. I'll have to look into SWIG. Thanks for the tip.
-
nickfinity over 12 yearsFound this (stackoverflow.com/a/3452258/978528) and setup Eclipse to run javah. Working good now. Now I have to implement the rest of the stuff. Hopefully will be straightforward.
-
Aniket over 11 years@GooseSerbus what about parameters used public static native boolean CreateSession(?,?);
-
GooseSerbus over 11 years@Aniket parameters are added onto the parameters in the C method e.g.:
public static native boolean CreateSession(boolean, Object);
would beJNIEXPORT jboolean JNICALL Java_com_example_NativeCode_CreateSession(JniEnv* env, jclass clazz, jboolean b, jobject o)