Calling C++ dll from Java

28,006

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.

Share:
28,006
nickfinity
Author by

nickfinity

Updated on July 09, 2022

Comments

  • nickfinity
    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
    Andy Thomas over 12 years
    +1 for mentioning that javah should be used to generate the function signatures.
  • nickfinity
    nickfinity over 12 years
    That 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
    nickfinity over 12 years
    It 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
    nickfinity over 12 years
    Found 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
    Aniket over 11 years
    @GooseSerbus what about parameters used public static native boolean CreateSession(?,?);
  • GooseSerbus
    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 be JNIEXPORT jboolean JNICALL Java_com_example_NativeCode_CreateSession(JniEnv* env, jclass clazz, jboolean b, jobject o)