Reputation: 4857
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
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
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
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