[typhoon@localhost sandbox]$ ls 0_guide.txt [typhoon@localhost sandbox]$ mkdir -p src/tfw/rsch/jni [typhoon@localhost sandbox]$ ls 0_guide.txt src [typhoon@localhost sandbox]$ vi src/tfw/rsch/jni/MainTest.java [typhoon@localhost sandbox]$ vi src/tfw/rsch/jni/JniTest_01_Loader.java [typhoon@localhost sandbox]$ vi src/tfw/rsch/jni/JniTest_01_Caller.java [typhoon@localhost sandbox]$ vi src/tfw/rsch/jni/JniTest_02_LoadAndCall.java [typhoon@localhost sandbox]$ vi src/tfw/rsch/jni/JniTest_03_ToPureLocal.java [typhoon@localhost sandbox]$ ls src/tfw/rsch/jni JniTest_01_Caller.java JniTest_01_Loader.java JniTest_02_LoadAndCall.java JniTest_03_ToPureLocal.java MainTest.java [typhoon@localhost sandbox]$ |
/** * This file is a component of FREE SOFTWARE.<br /> * <br /> * Any entity with self-awareness, or organization are allowed to use, modify or * redistribute this according to the second version of "GNU Public License".<br /> * <br /> * The goal of this distribution is that this software being useful and helpful, * FOR A PARTICULAR PURPOSE.<br /> */ package tfw.rsch.jni; import tfw.base.util.array.ArrayToolE; import tfw.base.util.text.TextToolE; /** * Main class, to run a test method of JNI loading and calling.<br /> * * @author Typhoon.Free.Wolf * @version 2015-06-25_18-33 */ public class MainTest { /** * Main method, to run a test of JNI loading and calling.<br /> * * @author Typhoon.Free.Wolf * @version 2015-04-09_15-54 * @param str1dCmdArgs * - Command line arguments.<br /> */ public static void main(String[] str1dCmdArgs) { new MainTest().test(str1dCmdArgs); } /** * General test method.<br /> * * @author Typhoon.Free.Wolf * @version 2015-06-25_18-29 * @param str1dArgs * - Arguments.<br /> */ private void test(String[] str1dArgs) { try { // [S] Pre-processing incoming arguments into a single string. String strArgText = ArrayToolE.arrayForConsole(str1dArgs); if (null == strArgText) { strArgText = ""; } else if ("null".equals(strArgText)) { strArgText = null; } // [E] Pre-processing incoming arguments into a single string. test_01(); test_02(strArgText); test_03(strArgText); } catch (Throwable t) { t.printStackTrace(); } } /** * Test 01: Basic loading and calling of the native library.<br /> * * @author Typhoon.Free.Wolf * @version 2015-05-26_16-26 */ private void test_01() { // Loading native library. new JniTest_01_Loader(); // Calling native method of native library. JniTest_01_Caller jt_01 = new JniTest_01_Caller(); jt_01.println(); jt_01.nativePrintln(); } /** * Test 02: <strong>Argument</strong> passing in and <strong>return * value</strong> retrieving.<br /> * * @author Typhoon.Free.Wolf * @version 2015-06-25_18-29 * @param strArgText * - Text argument to the native library.<br /> */ private void test_02(String strArgText) { // Loading native library during class initializing. JniTest_02_LoadAndCall jt_02 = new JniTest_02_LoadAndCall(); { String strMethodHead = TextToolE.concat("\tpublic String jt_02.javaManipulate(", ((null == strArgText) ? "null" : ("\"" + strArgText + "\"")) + ")\n\t{"); System.out.println(strMethodHead); // Calling the java method. String strRst = jt_02.javaManipulate(strArgText); String strMethodTail = TextToolE .concat("\t}\n\tGot Return Value: ", ((null == strRst) ? "null" : ("\"" + strRst + "\""))); System.out.println(strMethodTail); } System.out.println(); { String strMethodHead = TextToolE.concat( "\tpublic native String jt_02.nativeManipulate(", ((null == strArgText) ? "null" : ("\"" + strArgText + "\"")) + ")\n\t{"); System.out.println(strMethodHead); // Calling the native method, here! String strOut = jt_02.nativeManipulate(strArgText); String strMethodTail = TextToolE .concat("\t}\n\tGot Return Value: ", ((null == strOut) ? "null" : ("\"" + strOut + "\""))); System.out.println(strMethodTail); } } /** * Test 03: Calling to the <u><strong>pure local native library</strong> * that without any relationship to JNI or java</u> through the * <u><strong>native JNI-bridge library</strong></u>.<br /> * * @author Typhoon.Free.Wolf * @version 2015-06-25_18-29 * @param strArgText * - Text argument to the native library.<br /> */ private void test_03(String strArgText) { // Loading native library during class initializing. JniTest_03_ToPureLocal jt_03 = new JniTest_03_ToPureLocal(); { String strMethodHead = TextToolE.concat("\tpublic String jt_03.javaManipulate(", ((null == strArgText) ? "null" : ("\"" + strArgText + "\"")) + ")\n\t{"); System.out.println(strMethodHead); // Calling the java method. String strRst = jt_03.javaManipulate(strArgText); String strMethodTail = TextToolE .concat("\t}\n\tGot Return Value: ", ((null == strRst) ? "null" : ("\"" + strRst + "\""))); System.out.println(strMethodTail); } System.out.println(); { String strMethodHead = TextToolE.concat( "\tpublic native String jt_03.nativeManipulate(", ((null == strArgText) ? "null" : ("\"" + strArgText + "\"")) + ")\n\t{"); System.out.println(strMethodHead); // Calling the native method, here! String strOut = jt_03.nativeManipulate(strArgText); String strMethodTail = TextToolE .concat("\t}\n\tGot Return Value: ", ((null == strOut) ? "null" : ("\"" + strOut + "\""))); System.out.println(strMethodTail); } } } |
/** * This file is a component of FREE SOFTWARE.<br /> * <br /> * Any entity with self-awareness, or organization are allowed to use, modify or * redistribute this according to the second version of "GNU Public License".<br /> * <br /> * The goal of this distribution is that this software being useful and helpful, * FOR A PARTICULAR PURPOSE.<br /> */ package tfw.rsch.jni; /** * Test 01:<br /> * This class loads the native library (shared object, or dynamic link library, * and so on) during class initializing.<br /> * * @author Typhoon.Free.Wolf * @version 2015-05-26_16-30 */ public class JniTest_01_Loader { /** * Make sure to run during class initializing.<br /> */ static { loadNativeLibrary(); } /** * Loads the native library (shared object, or dynamic link library, and so * on).<br /> * * @author Typhoon.Free.Wolf * @version 2015-05-26_15-56 */ private static void loadNativeLibrary() { // Loading native library file "libJniTest_01_ThisNameIsOK.so" (or // "JniTest_01_ThisNameIsOK.dll", and so on) according to the library // name "JniTest_01_ThisNameIsOK". String strNativeLibraryName = "JniTest_01_AnyNameIsOK"; System.out.println("Loading \"" + strNativeLibraryName + "\"..."); System.loadLibrary(strNativeLibraryName); // <== Loading, here! System.out.println("Loaded."); } } |
/** * This file is a component of FREE SOFTWARE.<br /> * <br /> * Any entity with self-awareness, or organization are allowed to use, modify or * redistribute this according to the second version of "GNU Public License".<br /> * <br /> * The goal of this distribution is that this software being useful and helpful, * FOR A PARTICULAR PURPOSE.<br /> */ package tfw.rsch.jni; /** * Test 01:<br /> * This class provides an entrance to the native method in the native library * (shared object, or dynamic link library, and so on) for java calling.<br /> * * @author Typhoon.Free.Wolf * @version 2015-05-26_16-30 */ public class JniTest_01_Caller { /** * A java method, prints a message to the standard-out.<br /> * * @author Typhoon.Free.Wolf * @version 2015-04-11_14-09 */ public void println() { System.out.println("\tJava:\tWorks!"); } /** * Entrance to the native method in the native library (shared object, or * dynamic link library, and so on).<br /> * The corresponding native method is supposed to print a message to the * standard-out, just like what the java one above does.<br /> * * @author Typhoon.Free.Wolf * @version 2015-04-11_14-09 */ public native void nativePrintln(); } |
/** * This file is a component of FREE SOFTWARE.<br /> * <br /> * Any entity with self-awareness, or organization are allowed to use, modify or * redistribute this according to the second version of "GNU Public License".<br /> * <br /> * The goal of this distribution is that this software being useful and helpful, * FOR A PARTICULAR PURPOSE.<br /> */ package tfw.rsch.jni; import tfw.base.util.misc.MiscToolE; import tfw.base.util.text.TextToolE; /** * Test 02: This class<br /> * <ul> * <li>Loads the native library (shared object, or dynamic link library, and so * on) during class initializing;<br /> * </li> * <li>Provides an entrance to the native method in the native library.<br /> * </li> * </ul> * * @author Typhoon.Free.Wolf * @version 2015-06-25_18-38 */ public class JniTest_02_LoadAndCall { /** * Make sure to run during class initializing.<br /> */ static { loadNativeLibrary(); } /** * Loads the native library (shared object, or dynamic link library, and so * on).<br /> * * @author Typhoon.Free.Wolf * @version 2015-05-26_15-58 */ private static void loadNativeLibrary() { // Loading native library file "libJniTest_02.so" (or "JniTest_02.dll", // and so on) according to the library name "JniTest_02". String strNativeLibraryName = "JniTest_02"; System.out.println("Loading \"" + strNativeLibraryName + "\"..."); System.loadLibrary(strNativeLibraryName); // <== Loading, here! System.out.println("Loaded."); } /** * A java method.<br /> * Prints the incoming text string to the standard-out, then receives the * text string from the standard-input and finally returns it.<br /> * * @author Typhoon.Free.Wolf * @version 2015-06-25_18-36 * @param strText * - Incoming text string.<br /> * @return A text string from the standard-input, <strong>could be * null.</strong><br /> */ public String javaManipulate(String strText) { // Printing the received argument. String strReceiveText = TextToolE.concat("\t\tJava:\n\n\t\tArgument:\n\t\t\t", (null == strText) ? "null" : ("\"" + strText + "\"")); System.out.println(strReceiveText); // [S] Receiving a text string for standard input. System.out .print("\t\tUser Input (\"null\" would be considered as null):\n\t\t\t"); String strUserInputText = MiscToolE.getline(System.in); System.out.println("\t\tUser Input Received:\n\t\t\t" + ((null == strUserInputText) ? "null" : ("\"" + strUserInputText + "\""))); // [E] Receiving a text string for standard input. // [S] Printing the value which to be returned. String strReturnValue = "null".equals(strUserInputText) ? null : strUserInputText; System.out.println("\t\tReturns:\n\t\t\t" + ((null == strReturnValue) ? "null" : ("\"" + strReturnValue + "\""))); // [E] Printing the value which to be returned. // Returning. return strReturnValue; } /** * Entrance to the native method in the native library (shared object, or * dynamic link library, and so on).<br /> * The corresponding native method is supposed to print the incoming text * string to the standard-out, then receive the text string from the * standard-input and finally return it, just like what the java one above * does.<br /> * * @author Typhoon.Free.Wolf * @version 2015-04-11_14-10 * @param strText * - Incoming text string.<br /> * @return A text string actually returned from the native method, * <strong>could be null.</strong><br /> */ public native String nativeManipulate(String strText); } |
/** * This file is a component of FREE SOFTWARE.<br /> * <br /> * Any entity with self-awareness, or organization are allowed to use, modify or * redistribute this according to the second version of "GNU Public License".<br /> * <br /> * The goal of this distribution is that this software being useful and helpful, * FOR A PARTICULAR PURPOSE.<br /> */ package tfw.rsch.jni; import tfw.base.util.misc.MiscToolE; import tfw.base.util.text.TextToolE; /** * Test 03: This class<br /> * <ul> * <li>Loads the native library (shared object, or dynamic link library, and so * on) during class initializing;<br /> * </li> * <li>Provides an entrance to the native method in the <strong><u>native * JNI-bridge library</u></strong>.<br /> * </li> * <li>The <u><strong>native JNI-bridge library</strong></u> is to call another * <u><strong>pure, local native library</strong> that without any relationship * to JNI or java</u>.<br /> * </li> * </ul> * * @author Typhoon.Free.Wolf * @version 2015-06-25_18-40 */ public class JniTest_03_ToPureLocal { /** * Make sure to run during class initializing.<br /> */ static { loadNativeLibrary(); } /** * Loads the native library (shared object, or dynamic link library, and so * on).<br /> * * @author Typhoon.Free.Wolf * @version 2015-05-26_15-58 */ private static void loadNativeLibrary() { // Loading native library file "libJniTest_03.so" (or "JniTest_03.dll", // and so on) according to the library name "JniTest_03". String strNativeLibraryName = "JniTest_03"; System.out.println("Loading \"" + strNativeLibraryName + "\"..."); System.loadLibrary(strNativeLibraryName); // <== Loading, here! System.out.println("Loaded."); } /** * A java method.<br /> * Prints the incoming text string to the standard-out, then receives the * text string from the standard-input and finally returns it.<br /> * * @author Typhoon.Free.Wolf * @version 2015-06-25_18-36 * @param strText * - Incoming text string.<br /> * @return A text string from the standard-input, <strong>could be * null.</strong><br /> */ public String javaManipulate(String strText) { // Printing the received argument. String strReceiveText = TextToolE.concat("\t\tJava:\n\n\t\tArgument:\n\t\t\t", (null == strText) ? "null" : ("\"" + strText + "\"")); System.out.println(strReceiveText); // [S] Receiving a text string for standard input. System.out .print("\t\tUser Input (\"null\" would be considered as null):\n\t\t\t"); String strUserInputText = MiscToolE.getline(System.in); System.out.println("\t\tUser Input Received:\n\t\t\t" + ((null == strUserInputText) ? "null" : ("\"" + strUserInputText + "\""))); // [E] Receiving a text string for standard input. // [S] Printing the value which to be returned. String strReturnValue = "null".equals(strUserInputText) ? null : strUserInputText; System.out.println("\t\tReturns:\n\t\t\t" + ((null == strReturnValue) ? "null" : ("\"" + strReturnValue + "\""))); // [E] Printing the value which to be returned. // Returning. return strReturnValue; } /** * Entrance to the native method in the native library (shared object, or * dynamic link library, and so on).<br /> * The corresponding native method is supposed to print the incoming text * string to the standard-out, then receive the text string from the * standard-input and finally return it, just like what the java one above * does.<br /> * * @author Typhoon.Free.Wolf * @version 2015-04-11_14-10 * @param strText * - Incoming text string.<br /> * @return A text string actually returned from the native method, * <strong>could be null.</strong><br /> */ public native String nativeManipulate(String strText); } |
[typhoon@localhost sandbox]$ cp -a ../lib . [typhoon@localhost sandbox]$ mkdir classes [typhoon@localhost sandbox]$ ls 0_guide.txt classes lib src [typhoon@localhost sandbox]$ ls lib # ← 上述源代碼引用的工具類在這個文件夾裏。 tfw-base.aij.jar tfw-base.v2.2.8_2014-12-22_22-00.longest_night.jre150.aij.jar # ↑ ↖_ 工具類「ArrayToolE」、「MiscToolE」和「TextToolE」所在。 # `- 指向「tfw-base.v2.2.8_2014-12-22_22-00.longest_night.jre150.aij.jar」的符號連接。 [typhoon@localhost sandbox]$ javac -classpath lib/tfw-base.aij.jar -d classes src/tfw/rsch/jni/*.java [typhoon@localhost sandbox]$ ls classes/tfw/rsch/jni JniTest_01_Caller.class JniTest_01_Loader.class JniTest_02_LoadAndCall.class JniTest_03_ToPureLocal.class MainTest.class [typhoon@localhost sandbox]$ |
[typhoon@localhost sandbox]$ vi build_jni.sh [typhoon@localhost sandbox]$ ls 0_guide.txt build_jni.sh classes lib src [typhoon@localhost sandbox]$ sh build_jni.sh javah -classpath classes -o c_include/JniTest_01_Any_name_is_OK.h tfw.rsch.jni.JniTest_01_Caller;echo $?; 0 javah -classpath classes -o c_include/JniTest_02.h tfw.rsch.jni.JniTest_02_LoadAndCall;echo $?; 0 javah -classpath classes -o c_include/JniTest_03.h tfw.rsch.jni.JniTest_03_ToPureLocal;echo $?; 0 [typhoon@localhost sandbox]$ ls 0_guide.txt build_jni.sh c_include classes lib src [typhoon@localhost sandbox]$ ls c_include JniTest_01_Any_name_is_OK.h JniTest_02.h JniTest_03.h [typhoon@localhost sandbox]$ |
#!/bin/sh # JNI head file generating: CLAZZ="tfw.rsch.jni.JniTest_01_Caller"; OUTPUT="c_include/JniTest_01_Any_name_is_OK.h"; echo "javah -classpath classes -o $OUTPUT $CLAZZ;echo \$?;"; javah -classpath classes -o $OUTPUT $CLAZZ;echo $?; CLAZZ="tfw.rsch.jni.JniTest_02_LoadAndCall"; OUTPUT="c_include/JniTest_02.h"; echo "javah -classpath classes -o $OUTPUT $CLAZZ;echo \$?;"; javah -classpath classes -o $OUTPUT $CLAZZ;echo $?; CLAZZ="tfw.rsch.jni.JniTest_03_ToPureLocal"; OUTPUT="c_include/JniTest_03.h"; echo "javah -classpath classes -o $OUTPUT $CLAZZ;echo \$?;"; javah -classpath classes -o $OUTPUT $CLAZZ;echo $?; |
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class tfw_rsch_jni_JniTest_01_Caller */ #ifndef _Included_tfw_rsch_jni_JniTest_01_Caller #define _Included_tfw_rsch_jni_JniTest_01_Caller #ifdef __cplusplus extern "C" { #endif /* * Class: tfw_rsch_jni_JniTest_01_Caller * Method: nativePrintln * Signature: ()V */ JNIEXPORT void JNICALL Java_tfw_rsch_jni_JniTest_101_1Caller_nativePrintln (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif |
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class tfw_rsch_jni_JniTest_02_LoadAndCall */ #ifndef _Included_tfw_rsch_jni_JniTest_02_LoadAndCall #define _Included_tfw_rsch_jni_JniTest_02_LoadAndCall #ifdef __cplusplus extern "C" { #endif /* * Class: tfw_rsch_jni_JniTest_02_LoadAndCall * Method: nativeManipulate * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_tfw_rsch_jni_JniTest_102_1LoadAndCall_nativeManipulate (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif |
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class tfw_rsch_jni_JniTest_03_ToPureLocal */ #ifndef _Included_tfw_rsch_jni_JniTest_03_ToPureLocal #define _Included_tfw_rsch_jni_JniTest_03_ToPureLocal #ifdef __cplusplus extern "C" { #endif /* * Class: tfw_rsch_jni_JniTest_03_ToPureLocal * Method: nativeManipulate * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_tfw_rsch_jni_JniTest_103_1ToPureLocal_nativeManipulate (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif |
[typhoon@localhost sandbox]$ mkdir c_src [typhoon@localhost sandbox]$ ls 0_guide.txt build_jni.sh c_include classes c_src lib src [typhoon@localhost sandbox]$ vi c_src/JniTest_01_ANY_NAME_IS_OK.c [typhoon@localhost sandbox]$ vi c_src/JniTest_02.c [typhoon@localhost sandbox]$ vi c_src/JniTest_03.c [typhoon@localhost sandbox]$ vi c_src/PureLocalNoJava.c [typhoon@localhost sandbox]$ ls c_src JniTest_01_ANY_NAME_IS_OK.c JniTest_02.c JniTest_03.c PureLocalNoJava.c [typhoon@localhost sandbox]$ |
#include <jni.h> #include <stdio.h> #include <JniTest_01_Any_name_is_OK.h> JNIEXPORT void JNICALL Java_tfw_rsch_jni_JniTest_101_1Caller_nativePrintln (JNIEnv *env, jobject obj) { printf("\tJNI:\tWorks!\n"); return; } |
#include <jni.h> #include <stdio.h> #include <JniTest_02.h> void interactiveGetLine(char *strBuff, int intBuffSize) { printf("\t\tvoid interactiveGetLine(char *strBuff, int [%d])\n\t\t{\n", intBuffSize); // Receiving a text string for standard input, without line breaker. printf("\t\t\tUser Input:\n\t\t\t\t"); fgets(strBuff, intBuffSize, stdin); printf("\t\t\tUser Input Received:\n\t\t\t\t\"%s\"\n", strBuff); // [S] Setting the value index of first line breaker as string ending. int intIdx = 0; for (; intIdx < intBuffSize; intIdx++) { if ('\r' == strBuff[intIdx] || '\n' == strBuff[intIdx]) { strBuff[intIdx] = '\0'; break; } } printf("\t\t\tLine Breaker Removed:\n\t\t\t\t\"%s\"\n", strBuff); // [E] Setting the value index of first line breaker as string ending. printf("\t\t}\n"); } JNIEXPORT jstring JNICALL Java_tfw_rsch_jni_JniTest_102_1LoadAndCall_nativeManipulate (JNIEnv *jniEnv, jobject jobj, jstring jstrArg) { // Printing the received argument. printf("\t\tJNI:\n\n\t\tOriginal Argument:\n\t\t\t"); printf((NULL == jstrArg) ? "%s\n" : "\"%s\"\n", jstrArg); // Converting the received argument into a C styled string, and printing. const char *strConvertedArg = (NULL == jstrArg) ? NULL : (*jniEnv)->GetStringUTFChars(jniEnv, jstrArg, 0); printf("\t\tConverted Argument:\n\t\t\t"); printf((NULL == strConvertedArg) ? "%s\n" : "\"%s\"\n", strConvertedArg); // Now the JNI argument is useless, release it. (*jniEnv)->ReleaseStringUTFChars(jniEnv, jstrArg, strConvertedArg); // Receiving a line of user input from standard input into buffer. int MEANINGFUL_LENGTH = 256; int intBuffSize = MEANINGFUL_LENGTH + 1; char ch1dUserInputBuff[intBuffSize]; interactiveGetLine(ch1dUserInputBuff, intBuffSize); // Printing the value which to be returned. printf("\t\tReturn Value (\"NULL\" is considered as null):\n\t\t\t"); const char *strToReturn = (0 == strcmp(ch1dUserInputBuff, "NULL")) ? NULL : ch1dUserInputBuff; printf((NULL == strToReturn) ? "%s\n" : "\"%s\"\n", strToReturn); // Converting the return value into java string, and printing. jstring jstrToReturn = (*jniEnv)->NewStringUTF(jniEnv, strToReturn); printf("\t\tConverted:\n\t\t\t"); printf((NULL == jstrToReturn) ? "%s\n" : "\"%s\"\n", jstrToReturn); // Returning. return jstrToReturn; } |
#include <jni.h> #include <stdio.h> #include <JniTest_03.h> void checkString(char *strSrc, int intStartIdx, int intCheckCount) { int intIdx; int intFinalIdx = intStartIdx + intCheckCount; if (1 > intCheckCount) { printf("\nCheck count: %d From index %d Final index limit: %d.\nIndex:", intCheckCount, intStartIdx, intFinalIdx - 1); } printf("\nCheck count: [%d] From index [%d] to [%d]\nIndex:", intCheckCount, intStartIdx, intFinalIdx - 1); for (intIdx = 0; intIdx < intCheckCount; intIdx++) { printf("\t[%d]", intIdx); } printf("\nASCII:"); for (intIdx = 0; intIdx < intFinalIdx; intIdx++) { printf("\t[%d]", strSrc[intIdx]); } printf("\nChar:"); for (intIdx = 0; intIdx < intFinalIdx; intIdx++) { if ('\n' == strSrc[intIdx]) { printf("\t[\\n]"); } else { printf("\t[%c]", strSrc[intIdx]); } } printf("\n"); } void interactiveGetLine(char *strBuff, int intBuffSize) { printf("\t\tvoid interactiveGetLine(char *strBuff, int [%d])\n\t\t{\n", intBuffSize); printf("\t\t\tPure Local: Look Ma No Java!\n\n"); // Receiving a text string for standard input, without line breaker. printf("\t\t\tUser Input:\n\t\t\t\t"); fgets(strBuff, intBuffSize, stdin); printf("\t\t\tUser Input Received:\n\t\t\t\t\"%s\"\n", strBuff); // [S] Setting the value index of first line breaker as string ending. int intIdx = 0; for (; intIdx < intBuffSize; intIdx++) { if ('\r' == strBuff[intIdx] || '\n' == strBuff[intIdx]) { strBuff[intIdx] = '\0'; break; } } printf("\t\t\tLine Breaker Removed:\n\t\t\t\t\"%s\"\n", strBuff); // [E] Setting the value index of first line breaker as string ending. printf("\t\t}\n"); } JNIEXPORT jstring JNICALL Java_tfw_rsch_jni_JniTest_103_1ToPureLocal_nativeManipulate (JNIEnv *jniEnv, jobject jobj, jstring jstrArg) { // Printing the received argument. printf("\t\tJNI:\n\n\t\tOriginal Argument:\n\t\t\t"); printf((NULL == jstrArg) ? "%s\n" : "\"%s\"\n", jstrArg); // Converting the received argument into a C styled string, and printing. const char *strConvertedArg = (NULL == jstrArg) ? NULL : (*jniEnv)->GetStringUTFChars(jniEnv, jstrArg, 0); printf("\t\tConverted Argument:\n\t\t\t"); printf((NULL == strConvertedArg) ? "%s\n" : "\"%s\"\n", strConvertedArg); // Now the JNI argument is useless, release it. (*jniEnv)->ReleaseStringUTFChars(jniEnv, jstrArg, strConvertedArg); // Receiving a line of user input from standard input into buffer. int MEANINGFUL_LENGTH = 256; int intBuffSize = MEANINGFUL_LENGTH + 1; char ch1dUserInputBuff[intBuffSize]; interactiveGetLine(ch1dUserInputBuff, intBuffSize); // Printing the value which to be returned. printf("\t\tReturn Value (\"NULL\" is considered as null):\n\t\t\t"); const char *strToReturn = (0 == strcmp(ch1dUserInputBuff, "NULL")) ? NULL : ch1dUserInputBuff; printf((NULL == strToReturn) ? "%s\n" : "\"%s\"\n", strToReturn); // Converting the return value into java string, and printing. jstring jstrToReturn = (*jniEnv)->NewStringUTF(jniEnv, strToReturn); printf("\t\tConverted:\n\t\t\t"); printf((NULL == jstrToReturn) ? "%s\n" : "\"%s\"\n", jstrToReturn); // Returning. return jstrToReturn; } |
#include <stdio.h> void interactiveGetLine(char *strBuff, int intBuffSize) { printf("\t\tvoid interactiveGetLine(char *strBuff, int [%d])\n\t\t{\n", intBuffSize); printf("\t\t\tPure Local:\n\n"); // Receiving a text string for standard input, without line breaker. printf("\t\t\tUser Input:\n\t\t\t\t"); fgets(strBuff, intBuffSize, stdin); printf("\t\t\tUser Input Received:\n\t\t\t\t\"%s\"\n", strBuff); // [S] Setting the value index of first line breaker as string ending. int intIdx = 0; for (; intIdx < intBuffSize; intIdx++) { if ('\r' == strBuff[intIdx] || '\n' == strBuff[intIdx]) { strBuff[intIdx] = '\0'; break; } } printf("\t\t\tLine Breaker Removed:\n\t\t\t\t\"%s\"\n", strBuff); // [E] Setting the value index of first line breaker as string ending. printf("\t\t}\n"); } |
[typhoon@localhost sandbox]$ vi build_native.sh [typhoon@localhost sandbox]$ ls 0_guide.txt build_jni.sh build_native.sh c_include classes c_src lib src [typhoon@localhost sandbox]$ sh build_native.sh gcc c_src/JniTest_01_ANY_NAME_IS_OK.c -fPIC -shared -I c_include -I /usr/lib/jvm/java-1.7.0-openjdk.x86_64/include -I /usr/lib/jvm/java-1.7.0-openjdk.x86_64/include/linux -o lib/libJniTest_01_AnyNameIsOK.so;echo $?; 0 gcc c_src/JniTest_02.c -fPIC -shared -I c_include -I /usr/lib/jvm/java-1.7.0-openjdk.x86_64/include -I /usr/lib/jvm/java-1.7.0-openjdk.x86_64/include/linux -o lib/libJniTest_02.so;echo $?; 0 gcc c_src/PureLocalNoJava.c -fPIC -shared -o lib/libPureLocalNoJava.so;echo $?; 0 gcc c_src/JniTest_03.c -fPIC -shared -I c_include -I /usr/lib/jvm/java-1.7.0-openjdk.x86_64/include -I /usr/lib/jvm/java-1.7.0-openjdk.x86_64/include/linux -L /ext/var/home.123/typhoon/work/Eclipse.Projects/java.tfw.jni_rsch/sandbox/lib -l PureLocalNoJava -o lib/libJniTest_03.so;echo $?; 0 chmod 644 lib/*.so;echo $?; 0 [typhoon@localhost sandbox]$ ls lib libJniTest_01_AnyNameIsOK.so libJniTest_02.so libJniTest_03.so libPureLocalNoJava.so tfw-base.aij.jar tfw-base.v2.2.8_2014-12-22_22-00.longest_night.jre150.aij.jar [typhoon@localhost sandbox]$ |
#!/bin/sh # Native library compiling: # JNI related: C_SOURCE_FILE="c_src/JniTest_01_ANY_NAME_IS_OK.c"; OUTPUT="lib/libJniTest_01_AnyNameIsOK.so"; echo "gcc $C_SOURCE_FILE -fPIC -shared -I c_include -I $JAVA_HOME/include -I $JAVA_HOME/include/linux $3 -o $OUTPUT;echo \$?;"; gcc $C_SOURCE_FILE -fPIC -shared -I c_include -I $JAVA_HOME/include -I $JAVA_HOME/include/linux $3 -o $OUTPUT;echo $?; # JNI related: C_SOURCE_FILE="c_src/JniTest_02.c"; OUTPUT="lib/libJniTest_02.so"; echo "gcc $C_SOURCE_FILE -fPIC -shared -I c_include -I $JAVA_HOME/include -I $JAVA_HOME/include/linux $3 -o $OUTPUT;echo \$?;"; gcc $C_SOURCE_FILE -fPIC -shared -I c_include -I $JAVA_HOME/include -I $JAVA_HOME/include/linux $3 -o $OUTPUT;echo $?; # Pure local: C_SOURCE_FILE="c_src/PureLocalNoJava.c"; OUTPUT="lib/libPureLocalNoJava.so"; echo "gcc $C_SOURCE_FILE -fPIC -shared -o $OUTPUT;echo \$?;"; gcc $C_SOURCE_FILE -fPIC -shared -o $OUTPUT;echo $?; # JNI related: C_SOURCE_FILE="c_src/JniTest_03.c"; OUTPUT="lib/libJniTest_03.so"; LIB_PATH="$(pwd)/lib"; LIB_NAME="PureLocalNoJava"; echo "gcc $C_SOURCE_FILE -fPIC -shared -I c_include -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -L $LIB_PATH -l $LIB_NAME -o $OUTPUT;echo \$?;"; gcc $C_SOURCE_FILE -fPIC -shared -I c_include -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -L $LIB_PATH -l $LIB_NAME -o $OUTPUT;echo $?; # Permission: echo "chmod 644 lib/*.so;echo \$?;"; chmod 644 lib/*.so;echo $?; |
[typhoon@localhost sandbox]$ alias jrun='java -classpath classes:lib/tfw-base.aij.jar -Djava.library.path=lib' [typhoon@localhost sandbox]$ export LD_LIBRARY_PATH=LD_LIBRARY_PATH:$(pwd)/lib [typhoon@localhost sandbox]$ echo $LD_LIBRARY_PATH LD_LIBRARY_PATH:/home/typhoon/123/work/Eclipse.Projects/java.tfw.jni_rsch/sandbox/lib [typhoon@localhost sandbox]$ ldd lib/libJniTest_03.so ldd: 警告: 你沒有執行權限 `lib/libJniTest_03.so' linux-vdso.so.1 => (0x00007ffff51e5000) libPureLocalNoJava.so => /home/typhoon/123/work/Eclipse.Projects/java.tfw.jni_rsch/sandbox/lib/libPureLocalNoJava.so (0x00007fc9d0cb9000) libc.so.6 => /lib64/libc.so.6 (0x00007fc9d090d000) /lib64/ld-linux-x86-64.so.2 (0x0000003132400000) [typhoon@localhost sandbox]$ |
[typhoon@localhost sandbox]$ jrun tfw.rsch.jni.MainTest "一二三四五" "上山打老虎" Loading "JniTest_01_AnyNameIsOK"... Loaded. Java: Works! JNI: Works! Loading "JniTest_02"... Loaded. public String jt_02.javaManipulate("一二三四五, 上山打老虎") { Java: Argument: "一二三四五, 上山打老虎" User Input ("null" would be considered as null): 老虎沒打到,打到小松鼠! User Input Received: "老虎沒打到,打到小松鼠!" Returns: "老虎沒打到,打到小松鼠!" } Got Return Value: "老虎沒打到,打到小松鼠!" public native String jt_02.nativeManipulate("一二三四五, 上山打老虎") { JNI: Original Argument: " 4��" Converted Argument: "一二三四五, 上山打老虎" void interactiveGetLine(char *strBuff, int [257]) { User Input: NULL User Input Received: "NULL " Line Breaker Removed: "NULL" } Return Value ("NULL" is considered as null): (null) Converted: (null) } Got Return Value: null Loading "JniTest_03"... Loaded. public String jt_03.javaManipulate("一二三四五, 上山打老虎") { Java: Argument: "一二三四五, 上山打老虎" User Input ("null" would be considered as null): null User Input Received: "null" Returns: null } Got Return Value: null public native String jt_03.nativeManipulate("一二三四五, 上山打老虎") { JNI: Original Argument: " 4��" Converted Argument: "一二三四五, 上山打老虎" void interactiveGetLine(char *strBuff, int [257]) { Pure Local: Look Ma No Java! User Input: 老虎沒打到,打到小松鼠! User Input Received: "老虎沒打到,打到小松鼠! " Line Breaker Removed: "老虎沒打到,打到小松鼠!" } Return Value ("NULL" is considered as null): "老虎沒打到,打到小松鼠!" Converted: "h��" } Got Return Value: "老虎沒打到,打到小松鼠!" [typhoon@localhost sandbox]$ |