Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling C++ dll from Java

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

like image 220
nickfinity Avatar asked Feb 28 '12 16:02

nickfinity


People also ask

How do you call a DLL in Java?

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.

Can you call C code from Java?

Java native interface (JNI) is a framework provided by java that enables java programs to call native code and vice-versa. Using JNI a java program has the capability to call the native C code.

How can we call external DLL method from Java program?

You will need to use the Java Native Interface (JNI), which is a set of C/C++ functions that allow native code to interface with java code (i.e. receiving parameters from java function calls, returning results, etc). Write a wrapper C library that receive JNI calls and then call your external library.

Can a DLL be written in Java?

DLLs are linked directly when loaded. Java code needs a jvm, so you can only provide a dll that starts a jvm and starts code there, but not all necessarily stuff fits in the dll.


3 Answers

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.

like image 187
GooseSerbus Avatar answered Nov 15 '22 15:11

GooseSerbus


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.

like image 40
Jörn Horstmann Avatar answered Nov 15 '22 13:11

Jörn Horstmann


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.

like image 21
quaylar Avatar answered Nov 15 '22 15:11

quaylar