/** * Reports whether * the last column read had a value of SQL {@code NULL}. * Note that you must first call one of the getter methods * on a column to try to read its value and then call * the method {@code wasNull} to see if the value read was * SQL {@code NULL}. * * @return {@code true} if the last column value read was SQL * {@code NULL} and {@code false} otherwise * @throws SQLException if a database access error occurs or this method is * called on a closed result set */ booleanwasNull()throws SQLException;
#include<jni.h> #include<stdio.h> #include"TestJNIInstanceVariable.h" // jni方法的静态实现 JNIEXPORT void JNICALL Java_TestJNIInstanceVariable_modifyInstanceVariable (JNIEnv *env, jobject thisObj){ // Get a reference to this object's class jclass thisClass = (*env)->GetObjectClass(env, thisObj); // int // Get the Field ID of the instance variables "number" jfieldID fidNumber = (*env)->GetFieldID(env, thisClass, "number", "I"); if (NULL == fidNumber) return; // Get the int given the Field ID jint number = (*env)->GetIntField(env, thisObj, fidNumber); printf("In C, the int is %d\n", number); // Change the variable number = 99; (*env)->SetIntField(env, thisObj, fidNumber, number); // Get the Field ID of the instance variables "message" jfieldID fidMessage = (*env)->GetFieldID(env, thisClass, "message", "Ljava/lang/String;"); if (NULL == fidMessage) return; // String // Get the object given the Field ID jstring message = (*env)->GetObjectField(env, thisObj, fidMessage); // Create a C-string with the JNI String constchar *cStr = (*env)->GetStringUTFChars(env, message, NULL); if (NULL == cStr) return; printf("In C, the string is %s\n", cStr); (*env)->ReleaseStringUTFChars(env, message, cStr); // Create a new C-string and assign to the JNI string message = (*env)->NewStringUTF(env, "Hello from C"); if (NULL == message) return; // modify the instance variables (*env)->SetObjectField(env, thisObj, fidMessage, message); }
注意:
c 调用 java 的方法,类似于反射。 首先,需要获得类对象,然后再获取函数 id。 再调用get 和 set 函数,操作数据。
如果建立了局部对象, 需要释放空间, 以防数据泄露。
访问静态变量和静态函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
publicclassTestJNIStaticVariable { static { System.loadLibrary("myjni"); // nyjni.dll (Windows) or libmyjni.so (Unixes) } // Static variables privatestaticdoublenumber=55.66; // Native method that modifies the instance variables privatenativevoidmodifyStaticVariable(); publicstaticvoidmain(String args[]) { TestJNIStaticVariabletest=newTestJNIStaticVariable(); test.modifyStaticVariable(); System.out.println("In Java, the double is " + number); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#include<jni.h> #include<stdio.h> #include"TestJNIStaticVariable.h" JNIEXPORT void JNICALL Java_TestJNIStaticVariable_modifyStaticVariable (JNIEnv *env, jobject thisObj){ // Get a reference to this object's class jclass cls = (*env)->GetObjectClass(env, thisObj); // Read the int static variable and modify its value jfieldID fidNumber = (*env)->GetStaticFieldID(env, cls, "number", "D"); if (NULL == fidNumber) return; jdouble number = (*env)->GetStaticDoubleField(env, thisObj, fidNumber); printf("In C, the double is %f\n", number); number = 77.88; (*env)->SetStaticDoubleField(env, thisObj, fidNumber, number); }
publicclassTestJNICallBackMethod { static { System.loadLibrary("myjni"); // myjni.dll (Windows) or libmyjni.so (Unixes) } // Native method that calls back the Java methods below privatenativevoidnativeMethod(); // To be called back by the native code privatevoidcallback() { System.out.println("In Java"); } privatevoidcallback(String message) { System.out.println("In Java with " + message); } privatedoublecallbackAverage(int n1, int n2) { return ((double)n1 + n2) / 2.0; } // Static method to be called back privatestaticStringcallbackStatic() { return"From static Java method"; } publicstaticvoidmain(String args[]) { newTestJNICallBackMethod().nativeMethod(); } }
// In "win\jni_mh.h" - machine header which is machine dependent typedeflong jint; typedef __int64 jlong; typedefsignedchar jbyte; // In "jni.h" typedefunsignedchar jboolean; typedefunsignedshort jchar; typedefshort jshort; typedeffloat jfloat; typedefdouble jdouble; typedef jint jsize;
String
1 2 3 4 5 6 7 8 9 10 11 12
publicclassTestJNIString { static { System.loadLibrary("myjni"); // myjni.dll (Windows) or libmyjni.so (Unixes) } // Native method that receives a Java String and return a Java String privatenativeStringsayHello(String msg); publicstaticvoidmain(String args[]) { Stringresult=newTestJNIString().sayHello("Hello from Java"); System.out.println("In Java, the returned string is: " + result); } }
// UTF-8 String (encoded to 1-3 byte, backward compatible with 7-bit ASCII) // Can be mapped to null-terminated char-array C-string constchar * GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy); // Returns a pointer to an array of bytes representing the string in modified UTF-8 encoding. voidReleaseStringUTFChars(JNIEnv *env, jstring string, constchar *utf); // Informs the VM that the native code no longer needs access to utf. jstring NewStringUTF(JNIEnv *env, constchar *bytes); // Constructs a new java.lang.String object from an array of characters in modified UTF-8 encoding. jsize GetStringUTFLength(JNIEnv *env, jstring string); // Returns the length in bytes of the modified UTF-8 representation of a string. voidGetStringUTFRegion(JNIEnv *env, jstring str, jsize start, jsize length, char *buf); // Translates len number of Unicode characters beginning at offset start into modified UTF-8 encoding // and place the result in the given buffer buf. // Unicode Strings (16-bit character) const jchar * GetStringChars(JNIEnv *env, jstring string, jboolean *isCopy); // Returns a pointer to the array of Unicode characters voidReleaseStringChars(JNIEnv *env, jstring string, const jchar *chars); // Informs the VM that the native code no longer needs access to chars. jstring NewString(JNIEnv *env, const jchar *unicodeChars, jsize length); // Constructs a new java.lang.String object from an array of Unicode characters. jsize GetStringLength(JNIEnv *env, jstring string); // Returns the length (the count of Unicode characters) of a Java string. voidGetStringRegion(JNIEnv *env, jstring str, jsize start, jsize length, jchar *buf); // Copies len number of Unicode characters beginning at offset start to the given buffer buf
数组
1 2 3 4 5 6 7
privatenativedouble[] sumAndAverage(int[] numbers); publicstaticvoidmain(String args[]) { int[] numbers= {22, 33, 33}; double[] results=newTestJNIPrimitiveArray().sumAndAverage(numbers); System.out.println("In Java, the sum is " + results[0]); System.out.println("In Java, the average is " + results[1]); }
#include<jni.h> #include<stdio.h> #include"TestJNIConstructor.h" JNIEXPORT jobject JNICALL Java_TestJNIConstructor_getIntegerObject (JNIEnv *env, jobject thisObj, jint number){ // Get a class reference for java.lang.Integer jclass cls = (*env)->FindClass(env, "java/lang/Integer"); // Get the Method ID of the constructor which takes an int jmethodID midInit = (*env)->GetMethodID(env, cls, "<init>", "(I)V"); if (NULL == midInit) returnNULL; // Call back constructor to allocate a new instance, with an int argument jobject newObj = (*env)->NewObject(env, cls, midInit, number); // Try runnning the toString() on this newly create object jmethodID midToString = (*env)->GetMethodID(env, cls, "toString", "()Ljava/lang/String;"); if (NULL == midToString) returnNULL; jstring resultStr = (*env)->CallObjectMethod(env, newObj, midToString); constchar *resultCStr = (*env)->GetStringUTFChars(env, resultStr, NULL); printf("In C: the number is %s\n", resultCStr); return newObj; }
对象函数
1 2 3 4 5 6 7
jclass FindClass(JNIEnv *env, constchar *name); jobject NewObject(JNIEnv *env, jclass cls, jmethodID methodID, ...); jobject NewObjectA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args); jobject NewObjectV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args); //Constructs a new Java object.The method ID indicates which constructor method to invoke jobject AllocObject(JNIEnv *env, jclass cls); //Allocates a new Java object without invoking any of the constructors for the object.
#include<jni.h> #include<stdio.h> #include"TestJNIObjectArray.h" JNIEXPORT jobjectArray JNICALL Java_TestJNIObjectArray_sumAndAverage (JNIEnv *env, jobject thisObj, jobjectArray inJNIArray){ // Get a class reference for java.lang.Integer jclass classInteger = (*env)->FindClass(env, "java/lang/Integer"); // Use Integer.intValue() to retrieve the int jmethodID midIntValue = (*env)->GetMethodID(env, classInteger, "intValue", "()I"); if (NULL == midIntValue) returnNULL; // Get the value of each Integer object in the array jsize length = (*env)->GetArrayLength(env, inJNIArray); jint sum = 0; int i; for (i = 0; i < length; i++) { jobject objInteger = (*env)->GetObjectArrayElement(env, inJNIArray, i); if (NULL == objInteger) returnNULL; jint value = (*env)->CallIntMethod(env, objInteger, midIntValue); sum += value; } double average = (double)sum / length; printf("In C, the sum is %d\n", sum); printf("In C, the average is %f\n", average); // Get a class reference for java.lang.Double jclass classDouble = (*env)->FindClass(env, "java/lang/Double"); // Allocate a jobjectArray of 2 java.lang.Double jobjectArray outJNIArray = (*env)->NewObjectArray(env, 2, classDouble, NULL); // Construct 2 Double objects by calling the constructor jmethodID midDoubleInit = (*env)->GetMethodID(env, classDouble, "<init>", "(D)V"); if (NULL == midDoubleInit) returnNULL; jobject objSum = (*env)->NewObject(env, classDouble, midDoubleInit, (double)sum); jobject objAve = (*env)->NewObject(env, classDouble, midDoubleInit, average); // Set to the jobjectArray (*env)->SetObjectArrayElement(env, outJNIArray, 0, objSum); (*env)->SetObjectArrayElement(env, outJNIArray, 1, objAve); return outJNIArray; }
局部变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
publicclassTestJNIReference { static { System.loadLibrary("myjni"); // myjni.dll (Windows) or libmyjni.so (Unixes) } // A native method that returns a java.lang.Integer with the given int. privatenativeIntegergetIntegerObject(int number); // Another native method that also returns a java.lang.Integer with the given int. privatenativeIntegeranotherGetIntegerObject(int number); publicstaticvoidmain(String args[]) { TestJNIReferencetest=newTestJNIReference(); System.out.println(test.getIntegerObject(1)); System.out.println(test.getIntegerObject(2)); System.out.println(test.anotherGetIntegerObject(11)); System.out.println(test.anotherGetIntegerObject(12)); System.out.println(test.getIntegerObject(3)); System.out.println(test.anotherGetIntegerObject(13)); } }
#include<jni.h> #include<stdio.h> #include"TestJNIReference.h" // Global Reference to the Java class "java.lang.Integer" static jclass classInteger; static jmethodID midIntegerInit; jobject getInteger(JNIEnv *env, jobject thisObj, jint number){ // Get a class reference for java.lang.Integer if missing if (NULL == classInteger) { printf("Find java.lang.Integer\n"); classInteger = (*env)->FindClass(env, "java/lang/Integer"); } if (NULL == classInteger) returnNULL; // Get the Method ID of the Integer's constructor if missing if (NULL == midIntegerInit) { printf("Get Method ID for java.lang.Integer's constructor\n"); midIntegerInit = (*env)->GetMethodID(env, classInteger, "<init>", "(I)V"); } if (NULL == midIntegerInit) returnNULL; // Call back constructor to allocate a new instance, with an int argument jobject newObj = (*env)->NewObject(env, classInteger, midIntegerInit, number); printf("In C, constructed java.lang.Integer with number %d\n", number); return newObj; } JNIEXPORT jobject JNICALL Java_TestJNIReference_getIntegerObject (JNIEnv *env, jobject thisObj, jint number){ returngetInteger(env, thisObj, number); } JNIEXPORT jobject JNICALL Java_TestJNIReference_anotherGetIntegerObject (JNIEnv *env, jobject thisObj, jint number){ returngetInteger(env, thisObj, number); }
1 2 3 4 5 6 7 8 9 10
// Get a class reference for java.lang.Integer if missing if (NULL == classInteger) { printf("Find java.lang.Integer\n"); // FindClass returns a local reference jclass classIntegerLocal = (*env)->FindClass(env, "java/lang/Integer"); // Create a global reference from the local reference classInteger = (*env)->NewGlobalRef(env, classIntegerLocal); // No longer need the local reference, free it! (*env)->DeleteLocalRef(env, classIntegerLocal); }
<formaction="uploadFileAction"enctype="multipart/form-data" method="post"> <inputtype="file"name="filename"><inputtype="submit" value="Press"> to upload the file! </form>