JNI和Qt通信 (Part 2)

2014-11-24 10:41:13 · 作者: · 浏览: 1

Part2

JNI数据转换成C数据


e.g. jstring - GetStringUTFChars(), NewStringUTF(), ReleaseStringUTFChars()

12345 JNIEXPORT void JNICALL Java_JNISample_sampleFunction(JNIEnv* env, jobject obj, jstring name) { const char* pname = env->GetStringUTFChars(name, NULL); env->ReleaseStringUTFChars(name, pname); }


e.g. Array


123456789101112 JNIEXPORT jint JNICALL Java_IntArray_sumArray (JNIEnv *env, jobject obj, jintArray arr) { jint buf[10]; jint i, sum = 0; // This line is necessary, since Java arrays are not guaranteed // to have a continuous memory layout like C arrays. env->GetIntArrayRegion(arr, 0, 10, buf); for (i = 0; i < 10; i++) { sum += buf[i]; } return sum; }

http://ironurbane.iteye.com/blog/425513

JNI的数据定义


123456789101112 // In "win\jni_mh.h" - machine header which is machine dependenttypedef long jint;typedef __int64 jlong;typedef signed char jbyte; // In "jni.h"typedef unsigned char jboolean;typedef unsigned short jchar;typedef short jshort;typedef float jfloat;typedef double jdouble;typedef jint jsize;

C++ 调用Java方法


JNI数据类型


Java Type Native Type Description
boolean jboolean 8 bits, unsigned
byte jbyte 8 bits, signed
char jchar 16 bits, unsigned
double jdouble 64 bits
float jfloat 32 bits
int jint 32 bits, signed
long jlong 64 bits, signed
short jshort 16 bits, signed
void void N/A

JNI的类型签名

Java Type Signature
boolean Z
byte B
char C
double D
float F
int I
long J
void V
object Lfully-qualified-class;
type[] [type
method signature ( arg-types) ret-type

e.g.


Java side

123456789101112131415 class JNISample{ public native void launchSample(); static { System.loadLibrary("Sample"); } public static int add(int a,int b) { return a+b; } public boolean judge(boolean bool) { return !bool; }}

C++side


1234567891011121314151617181920212223242526 JNIEnv *env = GetJNIEnv(); //Get env from JNIjclass cls;cls = env->FindClass("JNISample");if(cls !=0){ printf("find java class success\n"); // constructor mid = env->GetMethodID(cls,"","()V"); if(mid !=0) { jobj=env->NewObject(cls,mid); } // static function mid = env->GetStaticMethodID( cls, "add", "(II)I"); if(mid !=0) { square = env->CallStaticIntMethod( cls, mid, 5,5); } // function returns boolean mid = env->GetMethodID( cls, "judge","(Z)Z"); if(mid !=0){ jnot = env->CallBooleanMethod(jobj, mid, 1); }}


查看属性和方法的签名


Java版本 "java -version"

反编译工具 javap:


1 javap -s -p -classpath R:\test.Demo

Check JNI version

123 #ifdef JNI_VERSION_1_4 printf("Version is 1.4 \n"); #endif

使用API


1 jint GetVersion(JNIEnv *env);

返回值需要转换, Need convert the result from DEC to HEX;

JNI实现过程中的Issue


x86 or x64 "Can't load load IA 32-bit dll on a amd 64 bit platform"

确定本机上的默认JVM的版本和动态库的版本一致(x86或x64), Make sure JAVA's default path; check with "java -version" in command line.

3rdParty can't find dependent libraries 保证所依赖的动态库都能被找到;

1) copy the dll into executable file's folder 2) System.load() the dlls by dependecy orders


JNI_CreateJavaVM failed

C++创建JVM调用Java方法

jvm.dll(C:\Program Files (x86)\Java\jdk1.7.0_17\jre\bin\client; C:\Program Files (x86)\Java\jdk1.7.0_17\jre\bin\server; need check); jvm.lib(C:\Program Files (x86)\Java\jdk1.7.0_17\lib)