我成功使用JNI调用了一些C代码,但是当我想要改成C++时,无论我尝试调用哪个方法,JNI都会抛出一个"UnsatisfiedLinkError"错误。
这个是正常的:
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
我使用这个时会遇到一个 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
生成的标题如下:
/* 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
以下是我的实现(.cpp),我省略了decrypt
方法:
#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)));
}
对于C版本,我只需要写return (*env)->NewStringUTF(env, encrypt((*env)->GetStringUTFChars(env, s, JNI_FALSE)));
即可。
C版本可行,而C++版本则失败了:
Exception in thread "main" java.lang.UnsatisfiedLinkError: de.zdv.research.emdu.CI3CppEncryptionTools.encrypt(Ljava/lang/String;)Ljava/lang/String;
有什么想法吗?
JNIEXPORT
和JNICALL
是为确保正确的C绑定而设计的宏,但我看到一些例子中它们被省略了,但仍然能够正常工作。 - yvesonline