- 在java中定义native method
- public native void set_intValue(int selfHashCode, int v);
- 从java中生成C++用头文件
- javah -jni -classpath bin -d hdr HelloWorld
- C++ project的配置
- include目录 c:\Program Files\Java\jdk1.7.0_02\include
- include目录 c:\Program Files\Java\jdk1.7.0_02\include\win32
- include目录 对应javaclass.h的位置
- C++中基本类型
- JNIENV - java的运行环境
- jobject - 代表java的instance
- jclass - 代表java的类
- 基本使用
- 在java中load C++的native 库
System.loadLibrary("myjnilib"); - C++ :根据jobject获取其jclass
jclass cls = (*env)->GetObjectClass(env, obj);
- C++ , 获取methodId
jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "(I)V");
if (mid == 0) {
return;
}
- C++, 调用Java method
(*env)->CallVoidMethod(env, obj, mid, depth);
- 其他返回类型的调用参见JNIENV的定义
- C++, 访问java的String
JNIEXPORT jstring JNICALL
Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring prompt)
{
char buf[128];
const char *str = (*env)->GetStringUTFChars(env, prompt, 0);
printf("%s", str);
(*env)->ReleaseStringUTFChars(env, prompt, str);- C++, 由C++String 到 java String
...
scanf("%s", buf);
return (*env)->NewStringUTF(env, buf);
}- 其他String相关的function
GetStringChars takes the Java string and returns a pointer to an array of Unicode characters that comprise the string.ReleaseStringChars releases the pointer to the array of Unicode characters.NewString constructs a new java.lang.String object from an array of Unicode characters.GetStringLength returns the length of a string that is comprised of an array of Unicode characters.GetStringUTFLength returns the length of a string if it is represented in the UTF-8 format
- C++, 访问java Array
JNIEXPORT jint JNICALL
Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)
{
int i, sum = 0;
jsize len = (*env)->GetArrayLength(env, arr);
...- 访问array的元素
GetObjectArrayElement returns the object element at a given index.SetObjectArrayElement updates the object element at a given index
jint *body = (*env)->GetIntArrayElements(env, arr, 0);
for (i=0; i<len; i++) {
sum += body[i];
}- 释放
(*env)->ReleaseIntArrayElements(env, arr, body, 0);
return sum;
- C++, 访问Java field
//get field id
fid = (*env)->GetStaticFieldID(env, cls, "si", "I");
fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;");
//get field value
si = (*env)->GetStaticIntField(env, cls, fid);
jstr = (*env)->GetObjectField(env, obj, fid);
- C++, 处理java中的Exception
JNIEXPORT void JNICALL
Java_CatchThrow_catchThrow(JNIEnv *env, jobject obj)
{
jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "()V");
jthrowable exc;
if (mid == 0) {
return;
}
(*env)->CallVoidMethod(env, obj, mid);
exc = (*env)->ExceptionOccurred(env);
if (exc) {
/* We don't do much with the exception, except that we print a
debug message using ExceptionDescribe, clear it, and throw
a new exception. */
jclass newExcCls;
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
if (newExcCls == 0) { /* Unable to find the new exception class, give up. */
return;
}
(*env)->ThrowNew(env, newExcCls, "thrown from C code");
}
}- It is extremely important to check, handle, and clear the pending exception before calling subsequent JNI functions. Calling arbitrary JNI functions with a pending exception may lead to unexpected results. You can safely call only a small number of JNI functions when there is a pending exception. These functions are
ExceptionOccurred, ExceptionDescribe, and ExceptionClear. - 线程
- C++, 根据名字查找类
jclass cls = env->FindClass("java/lang/String");