- 設定Putty Translation編碼,如下圖所示
- 選擇 Translation >> Remote character set: UTF-8
- 設定Putty window Fonts,如下圖所示
- 選擇 Fonts >> 按下 Font used for ordinary text (Change...)
- 選擇字型 "TlwgMono"
大功告成!
--- 特別感謝 David 技術教學 ---
We're born to fly, but spend whole life looking for wings.
vi ~/.bashrc
# For colourful man pages export PAGER="`which less` -s" export BROWSER="$PAGER" export LESS_TERMCAP_mb=$'\E[01;34m' export LESS_TERMCAP_md=$'\E[01;34m' export LESS_TERMCAP_me=$'\E[0m' export LESS_TERMCAP_se=$'\E[0m' export LESS_TERMCAP_so=$'\E[01;44;33m' export LESS_TERMCAP_ue=$'\E[0m' export LESS_TERMCAP_us=$'\E[01;33m'
source ~/.bashrc
/* This code is illegal */ jstring MyNewString(JNIEnv *env, jchar *chars, jint len) { static jclass stringClass = NULL; jmethodID cid; jcharArray elemArr; jstring result; if (stringClass == NULL) { stringClass = (*env)->FindClass(env, "java/lang/String"); if (stringClass == NULL) { return NULL; /* exception thrown */ } } /* It is wrong to use the cached stringClass here, because it may be invalid. */ cid = (*env)->GetMethodID(env, stringClass, "<init>", "([C)V"); ... elemArr = (*env)->NewCharArray(env, len); ... result = (*env)->NewObject(env, stringClass, cid, elemArr); (*env)->DeleteLocalRef(env, elemArr); return result; }The goal for caching stringClass in a static variable might have been to eliminate the overhead of repeatedly making the following function call:
FindClass(env, "java/lang/String");This is not the right approach because FindClass returns a local reference to the java.lang.String class object. To see why this is a problem, suppose that the native method implementation of C.f calls MyNewString:
JNIEXPORT jstring JNICALL Java_C_f(JNIEnv *env, jobject this) { char *c_str = ...; ... return MyNewString(c_str); }
#include <stdio.h> #include <jni.h> JNIEXPORT void JNICALL Java_InstanceFieldAccess_accessField(JNIEnv *env, jobject obj) { static jfieldID fid_s = NULL; /* cached field ID for s */ jstring jstr; const char *str; /* Get a reference to obj's class */ jclass cls = (*env)->GetObjectClass(env, obj); printf("In C:\n"); /* Look for the instance field s in cls */ if (fid_s == NULL) { fid_s = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;"); if (fid_s == NULL) { return; /* exception already thrown */ } } /* Read the instance field s */ jstr = (*env)->GetObjectField(env, obj, fid_s); str = (*env)->GetStringUTFChars(env, jstr, NULL); if (str == NULL) { return; /* out of memory */ } printf(" c.s = \"%s\"\n", str); (*env)->ReleaseStringUTFChars(env, jstr, str); jstr = (*env)->NewStringUTF(env, "123"); if (jstr == NULL) { return; /* out of memory */ } (*env)->SetObjectField(env, obj, fid_s, jstr); }
class InstanceMethodCall { private static native void initIDs(); private native void nativeMethod(); private void callback() { System.out.println("In Java"); } public static void main(String args[]) { InstanceMethodCall c = new InstanceMethodCall(); c.nativeMethod(); } static { System.loadLibrary("InstanceMethodCall"); initIDs(); } }
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class InstanceMethodCall */ #ifndef _Included_InstanceMethodCall #define _Included_InstanceMethodCall #ifdef __cplusplus extern "C" { #endif /* * Class: InstanceMethodCall * Method: initIDs * Signature: ()V */ JNIEXPORT void JNICALL Java_InstanceMethodCall_initIDs (JNIEnv *, jclass); /* * Class: InstanceMethodCall * Method: nativeMethod * Signature: ()V */ JNIEXPORT void JNICALL Java_InstanceMethodCall_nativeMethod (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
#include <stdio.h> #include <jni.h> jmethodID MID_InstanceMethodCall_callback; JNIEXPORT void JNICALL Java_InstanceMethodCall_initIDs(JNIEnv *env, jclass cls) { MID_InstanceMethodCall_callback = (*env)->GetMethodID(env, cls, "callback", "()V"); } JNIEXPORT void JNICALL Java_InstanceMethodCall_nativeMethod(JNIEnv *env, jobject obj) { printf("Output: In C code\n"); (*env)->CallVoidMethod(env, obj, MID_InstanceMethodCall_callback); }
Output: In C code
Output: In Java code
jstring MyNewString(JNIEnv *env, jchar *chars, jint len) { jclass stringClass; jmethodID cid; jcharArray elemArr; jstring result; stringClass = (*env)->FindClass(env, "java/lang/String"); if (stringClass == NULL) { return NULL; /* exception thrown */ } /* Get the method ID for the String(char[]) constructor */ cid = (*env)->GetMethodID(env, stringClass, "<init>", "([C)V"); if (cid == NULL) { return NULL; /* exception thrown */ } /* Create a char[] that holds the string characters */ elemArr = (*env)->NewCharArray(env, len); if (elemArr == NULL) { return NULL; /* exception thrown */ } (*env)->SetCharArrayRegion(env, elemArr, 0, len, chars); /* Construct a java.lang.String object */ result = (*env)->NewObject(env, stringClass, cid, elemArr); /* Free local references */ (*env)->DeleteLocalRef(env, elemArr); (*env)->DeleteLocalRef(env, stringClass); return result; }
result = (*env)->NewObject(env, stringClass, cid, elemArr);
result = (*env)->AllocObject(env, stringClass); if (result) { (*env)->CallNonvirtualVoidMethod(env, result, stringClass, cid, elemArr); /* we need to check for possible exceptions */ if ((*env)->ExceptionCheck(env)) { (*env)->DeleteLocalRef(env, result); result = NULL; } }
class InstanceMethodCall { private native void nativeMethod(); private void callback() { System.out.println("Output: In Java code"); } public static void main(String args[]) { InstanceMethodCall c = new InstanceMethodCall(); c.nativeMethod(); } static { System.loadLibrary("InstanceMethodCall"); } }
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class InstanceMethodCall */ #ifndef _Included_InstanceMethodCall #define _Included_InstanceMethodCall #ifdef __cplusplus extern "C" { #endif /* * Class: InstanceMethodCall * Method: nativeMethod * Signature: ()V */ JNIEXPORT void JNICALL Java_InstanceMethodCall_nativeMethod (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
#include <stdio.h> #include <jni.h> JNIEXPORT void JNICALL Java_InstanceMethodCall_nativeMethod(JNIEnv *env, jobject obj) { jclass cls = (*env)->GetObjectClass(env, obj); jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "()V"); if (mid == NULL) { return; /* method not found */ } printf("Output: In C code\n"); (*env)->CallVoidMethod(env, obj, mid); }
gcc -shared -I/usr/local/jdk1.6.20_21/include -I/usr/local/jdk1.6.20_21/include/linux InstanceMethodCall.c -o libInstanceMethodCall.so
Output: In C code
Output: In Java code
class StaticMethodCall { private native void nativeMethod(); private static void callback() { System.out.println("Output: In Java code"); } public static void main(String args[]) { StaticMethodCall c = new StaticMethodCall(); c.nativeMethod(); } static { System.loadLibrary("StaticMethodCall"); } }
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class StaticMethodCall */ #ifndef _Included_StaticMethodCall #define _Included_StaticMethodCall #ifdef __cplusplus extern "C" { #endif /* * Class: StaticMethodCall * Method: nativeMethod * Signature: ()V */ JNIEXPORT void JNICALL Java_StaticMethodCall_nativeMethod (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
#include <stdio.h> #include <jni.h> JNIEXPORT void JNICALL Java_StaticMethodCall_nativeMethod(JNIEnv *env, jobject obj) { jclass cls = (*env)->GetObjectClass(env, obj); jmethodID mid = (*env)->GetStaticMethodID(env, cls, "callback", "()V"); if (mid == NULL) { return; /* method not found */ } printf("Output: In C code\n"); (*env)->CallStaticVoidMethod(env, cls, mid); }
gcc -shared -I/usr/local/jdk1.6.20_21/include -I/usr/local/jdk1.6.20_21/include/linux StaticMethodCall.c -o libStaticMethodCall.so
Output: In C code
Output: In Java code
native private String getLine(String);
"(Ljava/lang/String;)Ljava/lang/String;"
public static void main(String[] args);
"([Ljava/lang/String;)V"
Compiled from "InstanceMethodCall.java"
class InstanceMethodCall extends java.lang.Object{
InstanceMethodCall();
Signature: ()V
private native void nativeMethod();
Signature: ()V
private void callback();
Signature: ()V
public static void main(java.lang.String[]);
Signature: ([Ljava/lang/String;)V
static {};
Signature: ()V }
class InstanceFieldAccess { private String s; private native void accessField(); public static void main(String args[]) { InstanceFieldAccess c = new InstanceFieldAccess(); c.s = "abc"; c.accessField(); System.out.println("In Java:"); System.out.println(" c.s = \"" + c.s + "\""); } static { System.loadLibrary("InstanceFieldAccess"); } }
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class InstanceFieldAccess */ #ifndef _Included_InstanceFieldAccess #define _Included_InstanceFieldAccess #ifdef __cplusplus extern "C" { #endif /* * Class: InstanceFieldAccess * Method: accessField * Signature: ()V */ JNIEXPORT void JNICALL Java_InstanceFieldAccess_accessField (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
#include <stdio.h> #include <jni.h> JNIEXPORT void JNICALL Java_InstanceFieldAccess_accessField(JNIEnv *env, jobject obj) { jfieldID fid; /* store the field ID */ jstring jstr; const char *str; /* Get a reference to obj's class */ jclass cls = (*env)->GetObjectClass(env, obj); printf("In C:\n"); /* Look for the instance field s in cls */ fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;"); if (fid == NULL) { return; /* failed to find the field */ } /* Read the instance field s */ jstr = (*env)->GetObjectField(env, obj, fid); str = (*env)->GetStringUTFChars(env, jstr, NULL); if (str == NULL) { return; /* out of memory */ } printf(" c.s = \"%s\"\n", str); (*env)->ReleaseStringUTFChars(env, jstr, str); /* Create a new string and overwrite the instance field */ jstr = (*env)->NewStringUTF(env, "123"); if (jstr == NULL) { return; /* out of memory */ } (*env)->SetObjectField(env, obj, fid, jstr); }
fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;");
jstr = (*env)->GetObjectField(env, obj, fid);
gcc -shared -I/usr/local/jdk1.6.20_21/include -I/usr/local/jdk1.6.20_21/include/linux InstanceFieldAccess.c -o libInstanceFieldAccess.so
In C: c.s = "abc"
In Java: c.s = "123"
class StaticFieldAccess { private static int si; private native void accessField(); public static void main(String args[]) { StaticFieldAccess c = new StaticFieldAccess(); StaticFieldAccess.si = 100; c.accessField(); System.out.println("In Java:"); System.out.println(" StaticFieldAccess.si = " + si); } static { System.loadLibrary("StaticFieldAccess"); } }
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class StaticFieldAccess */ #ifndef _Included_StaticFieldAccess #define _Included_StaticFieldAccess #ifdef __cplusplus extern "C" { #endif /* * Class: StaticFieldAccess * Method: accessField * Signature: ()V */ JNIEXPORT void JNICALL Java_StaticFieldAccess_accessField (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
#include <stdio.h> #include <jni.h> JNIEXPORT void JNICALL Java_StaticFieldAccess_accessField(JNIEnv *env, jobject obj) { jfieldID fid; /* store the field ID */ jint si; /* Get a reference to obj's class */ jclass cls = (*env)->GetObjectClass(env, obj); printf("In C:\n"); /* Look for the static field si in cls */ fid = (*env)->GetStaticFieldID(env, cls, "si", "I"); if (fid == NULL) { return; /* field not found */ } /* Access the static field si */ si = (*env)->GetStaticIntField(env, cls, fid); printf(" StaticFieldAccess.si = %d\n", si); (*env)->SetStaticIntField(env, cls, fid, 200); }
gcc -shared -I/usr/local/jdk1.6.20_21/include -I/usr/local/jdk1.6.20_21/include/linux StaticFieldAccess.c -o libStaticFieldAccess.so
In C: StaticFieldAccess.si = 100
In Java: StaticFieldAccess.si = 200
javap -s -p CLASS_NAME