- 設定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