yvesonline
yvesonline

Reputation: 4857

JNI and C++ - UnsatisfiedLinkError

I'm using JNI successfully to call some C code, however when I want to change to C++ JNI throws an UnsatisfiedLinkError whenever I try to call a method.

This one works:

g++ -c -Icryptopp562 -O3 -fPIC -fpermissive CI3CppEncryptionToolsImpl.cpp
gcc -I${JAVA_HOME}/include -O3 -shared -fPIC -o libCI3CppEncryptionTools.so de_zdv_research_emdu_CI3CppEncryptionTools.c CI3CppEncryptionToolsImpl.o -lcryptopp

With this one, I get an UnsatisfiedLinkError:

g++ -c -Icryptopp562 -O3 -fPIC -fpermissive CI3CppEncryptionToolsImpl.cpp
g++ -I${JAVA_HOME}/include -O3 -shared -fPIC -fpermissive -o libCI3CppEncryptionTools.so de_zdv_research_emdu_CI3CppEncryptionTools.cpp CI3CppEncryptionToolsImpl.o -lcryptopp

The generated header is as follows:

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

#ifndef _Included_de_zdv_research_emdu_CI3CppEncryptionTools
#define _Included_de_zdv_research_emdu_CI3CppEncryptionTools
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     de_zdv_research_emdu_CI3CppEncryptionTools
 * Method:    encrypt
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_de_zdv_research_emdu_CI3CppEncryptionTools_encrypt
  (JNIEnv *, jclass, jstring);

/*
 * Class:     de_zdv_research_emdu_CI3CppEncryptionTools
 * Method:    decrypt
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_de_zdv_research_emdu_CI3CppEncryptionTools_decrypt
  (JNIEnv *, jclass, jstring);

#ifdef __cplusplus
}
#endif
#endif

And my implementation (.cpp) is as follows, I omitted the decrypt method:

#include <jni.h>

#include "CI3CppEncryptionToolsImpl.h"

#include "de_zdv_research_emdu_CI3CppEncryptionTools.h"

jstring
Java_de_zdv_research_emdu_CI3CppEncryptionTools_encrypt(JNIEnv *env, jobject obj, jstring s) {

    return env->NewStringUTF(encrypt(env->GetStringUTFChars(s, JNI_FALSE)));

}

For the C version I simply write return (*env)->NewStringUTF(env, encrypt((*env)->GetStringUTFChars(env, s, JNI_FALSE))); instead.

The C version works, the C++ version fails with:

Exception in thread "main" java.lang.UnsatisfiedLinkError: de.zdv.research.emdu.CI3CppEncryptionTools.encrypt(Ljava/lang/String;)Ljava/lang/String;

Any ideas?

Upvotes: 3

Views: 1260

Answers (3)

manuell
manuell

Reputation: 7620

If you compile C++, you should have an extern "C" prefix before the functions declarations/definitions.

But there are others differences, see JNI Calls different in C vs C++?

Upvotes: 1

rachana
rachana

Reputation: 3424

In implementation (.cpp) you have written function as

jstring Java_de_zdv_research_emdu_CI3CppEncryptionTools_encrypt(JNIEnv *env, jobject obj, jstring s){
       //---------
}

Please write it as

JNIEXPORT jstring JNICALL Java_de_zdv_research_emdu_CI3CppEncryptionTools_encrypt
(JNIEnv *, jclass, jstring){
       //------------
}

Upvotes: 4

Jorge_B
Jorge_B

Reputation: 9872

Make sure java can find your dynamic native library in the same directory where you launch the JVM. Check also that your dynamic library is compiled for the same architecture as the JVM you are running your program with (for example, 32-bit for a 32-bit JMV, or 64 for a 64-bit JVM)

Upvotes: 0

Related Questions