[Android Application Development]-(15) JNI-Basic Data Type

Source: Internet
Author: User

This article describes how to easily learn JNI data types through examples. All languages have their basic data types. To learn more, you must understand the most basic things. In JNI, we will ask: how is the data type in Java mapped to the C/C ++ local language?

Directory:

1. A simple instance analysis

2. ing between Java and JNI Data Types

3. string processing

4. Array Processing

 


1. In a simple example analysis programming, it is common to PASS Parameters and return values to functions. Here we will introduce these technologies through several examples. Let's get started with a simple instance. Here we expand HelloWorld. java, print a string first, and then wait for the user to enter the code: (here I only list the C code)

[Cpp]
<SPAN style = "FONT-SIZE: 16px"> JNIEXPORT jstring JNICALL Java_org_winplus_basetype_HelloWorld_getLine (JNIEnv *, jobject, jstring); // (how is this code, see [Android Application Development]-(14) JNI-classic instance analysis) </SPAN>

JNIEXPORT jstring JNICALL comment (JNIEnv *, jobject, jstring); // (for details about how to use this code string, see [Android Application Development]-(14) JNI-typical instance analysis)
The getLine function receives three parameters: JNIEnv, jobject, and jstring. JNIEnv includes the JNI function table, for example:

The meaning of jobject depends on whether the method is static or an instance method. When the local method is used as a method, jobject is equivalent to the object itself, that is, this. When the local method acts as a static method, it points to the class. In this example, getline is a local instance method implementation, so jobject points to the object itself.

 

2. Type ing

For data types, java has two data types: Basic Data Types (int float, char) and reference type (instance, array ). The parameter types declared in the local method (native declared method) have corresponding types in JNI.

The ing between Java and JNI basic types is very direct. See the following table:

Java
Native (jni. h)
 
Boolean
Jboolean
 
Byte
Jbyte
 
Char
Jchar
 
Short
Jshort
 
Int
Jint
 
Long
Jlong
 
Float
Jfloat
 
Double
Jdouble
 


In addition to these types, the jstring, jclass, and jobjectArray structures are also defined. They all inherit from jobject.


The transfer of object types is much more complex than basic types. Objects at the Java layer are passed to the JNI layer as the opaque references pointer. Opaque references is the pointer type of C, which points to the internal data structure of JavaVM. The purpose of using this pointer is: The JNI user is not expected to understand the internal data structure of JAVAVM. Operations on the structures referred to by opaque references must be performed using the JNI method. For example, for the "java. lang. String" object, the type of the JNI layer is jstring. the operation on the opaque references must be performed through JNIEnv-> GetStringUTFChars. It should be noted that the process of programming must follow the principle. Do not bypass JNI for efficiency or ease of channel value, and directly operate opaque references.

 

3. string processing

1) instance

Now let's go back to the instance and see how to handle the String type passed from java. Please refer to the following code?

[Cpp]
JNIEXPORT jstring JNICALL Java_org_winplus_basetype_HelloWorld_getLine (JNIEnv * env, jobject obj, jstring prompt ){
Printf ("% s", prompt );
}

JNIEXPORT jstring JNICALL Java_org_winplus_basetype_HelloWorld_getLine (JNIEnv * env, jobject obj, jstring prompt ){
Printf ("% s", prompt );
}
Sorry, error: incorrect use of jstring as a char * pointer.

Here we need to use the JNI function to pack jstring as a C/C ++ string. JNI supports Unicode/UTF-8 character conversion. Unicode is encoded in 16-bits value; UTF-8 is a character encoding in a byte-length format and is compatible with 7-bits ASCII code. The UTF-8 string is the same as the C string, ending with NULL ('\ 0'), when the UTF-8 contains non-ASCII characters, with' \ 0' as the ending rules remain unchanged. The value range of 7-bit ASCII characters is 1-, and the value range of these characters is the same as that in the UTF-8. When the maximum bit is set, it indicates multi-byte encoding. Call GetStringUTFChars to convert a Unicode string to a UTF-8 string, if you are sure the string contains only 7-bit ASCII characters. This string can use related functions in the C library, such as printf.

[Cpp]
Java_org_winplus_basetype_HelloWorld_getLine (JNIEnv * env, jobject obj, jstring prompt ){
Char buf [128];
Const jbyte * str;
Str = (* env)-> GetStringUTFChars (env, prompt, NULL );
If (str = NULL ){
Return NULL;/* OutOfMemoryError already thrown */
}
Printf ("% s, str );
(* Env)-> ReleaseStringUTFChars (env, prompt, str );
/* We assume here that the user does not type more than 127 characters */
Scanf ("% 127 s, buf );
Return (* env)-> NewStringUTF (env, buf );
}

Java_org_winplus_basetype_HelloWorld_getLine (JNIEnv * env, jobject obj, jstring prompt ){
Char buf [128];
Const jbyte * str;
Str = (* env)-> GetStringUTFChars (env, prompt, NULL );
If (str = NULL ){
Return NULL;/* OutOfMemoryError already thrown */
}
Printf ("% s, str );
(* Env)-> ReleaseStringUTFChars (env, prompt, str );
/* We assume here that the user does not type more than 127 characters */
Scanf ("% 127 s, buf );
Return (* env)-> NewStringUTF (env, buf );
}

Check the returned value of GetStringUTFChars, because the function will be called for memory allocation. If this function fails, NULL is returned and an OutOfMemoryError is thrown. If an exception occurs, the execution track of the Code is not changed. Therefore, when Null is returned, the exception must be handled in a timely manner.

1) release the memory usage when calling GetStringUTFChars. ReleaseStringUTFChars

2) construct a new string using JNIEnv-> NewStringUTF. Similarly, if there is not enough memory, an OutOfMemoryError error will be thrown.

3) Other string operations

GetStringChars is a conversion function with Java internal Unicode to the local UTF-8. You can call GetStringLength to obtain the string length encoded in Unicode. You can also use strlen to calculate the return value of GetStringUTFChars to obtain the string length.

Const jchar * GetStringChars (JNIEnv * env, jstring str, jboolean * isCopy );

For details about how to use JNI, see pages 16-20.

4. Array Operations

Some Java code is very simple and will not be pasted out. Let's look at the C Code directly.

[Cpp]
JNIEXPORT jint JNICALL Java_org_winplus_basetype_IntArray_sumArray (JNIEnv * env,
Jobject obj, jintArray arr ){
// We cannot perform this operation directly.
/* This program is illegal! */
/* Int I, sum = 0;
For (I = 0; I <10; I ++ ){
Sum + = arr [I];
}*/
 
/// // Sample code 1 /// ////////////////////////
 
// Jint buf [10];
// Jint I, sum = 0;
// (* Env)-> GetIntArrayRegion (env, arr, 0, 10, buf );
// For (I = 0; I <10; I ++ ){
// Sum + = buf [I];
//}
// Return sum;
 
/// // Example code 2 // /////////////////////////
Jint * carr;
Jint j, sum1 = 0;
Carr = (* env)-> GetIntArrayElements (env, arr, NULL );
If (carr = NULL ){
Return 0;/* exception occurred */
}
For (j = 0; j <10; j ++ ){
Sum1 + = carr [j];
}
(* Env)-> ReleaseIntArrayElements (env, arr, carr, 0 );
Return sum1;

JNIEXPORT jint JNICALL Java_org_winplus_basetype_IntArray_sumArray (JNIEnv * env,
Jobject obj, jintArray arr ){
// We cannot perform this operation directly.
/* This program is illegal! */
/* Int I, sum = 0;
For (I = 0; I <10; I ++ ){
Sum + = arr [I];
}*/

/// // Sample code 1 /// ////////////////////////

// Jint buf [10];
// Jint I, sum = 0;
// (* Env)-> GetIntArrayRegion (env, arr, 0, 10, buf );
// For (I = 0; I <10; I ++ ){
// Sum + = buf [I];
//}
// Return sum;

/// // Example code 2 // /////////////////////////
Jint * carr;
Jint j, sum1 = 0;
Carr = (* env)-> GetIntArrayElements (env, arr, NULL );
If (carr = NULL ){
Return 0;/* exception occurred */
}
For (j = 0; j <10; j ++ ){
Sum1 + = carr [j];
}
(* Env)-> ReleaseIntArrayElements (env, arr, carr, 0 );
Return sum1;

In sample code 1, use GetIntArrayRegion to copy the array content to the buf. No cross-border exception detection is performed here, because there are 10 arrays, and parameter 3 is the starting position of the array to be copied, parameter 4 is the number of copied elements.

JNI supports SetIntArrayRegion and allows you to reset the values of one region in the array. Other basic types (boolean, short, and float) also support this function.

Sample Code 2 demonstrates returning a copy of the Java array through Get/Release <Type> ArrayElemetns (a good VM will return a direct pointer to the Java array, and mark the memory area. GC is not allowed ).

 

Author: tangcheng_ OK

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.