Java and C Conversion in jni

Source: Internet
Author: User

1. Passing strings
So far, Java programs have not yet passed parameters to C Programs, or C programs have passed parameters to Java programs. This routine passes in a string from the Java program to the C program. The C program converts the string into uppercase and then returns it to the Java program.

The Java source code is as follows.

Code List 15-6 routine for calling C Functions on Linux -- Sample1

Public class Sample1

{

Public native String stringMethod (String text );

Public static void main (String [] args)

{

System. loadLibrary ("Sample1 ");

Sample1 sample = new Sample1 ();

String text = sample. stringMethod ("Thinking In Java ");

System. out. println ("stringMethod:" + text );

}

}

Sample1.java calls the stringMethod () function In libSample1.so with the "Thinking In Java" as the parameter, and prints the output after obtaining the returned string.

The source program of Sample1.c is as follows.

Code List 15-7 routine for calling C Functions on Linux -- Sample1.c

# Include <Sample1.h>

# Include <string. h>

JNIEXPORT jstring JNICALL Java_Sample1_stringMethod (JNIEnv * env, jobject obj, jstring string)

{

Const char * str = (* env)-> GetStringUTFChars (env, string, 0 );

Char cap [128];

Strcpy (cap, str );

(* Env)-> ReleaseStringUTFChars (env, string, str );

Int I = 0;

For (I = 0; I <strlen (cap); I ++)

* (Cap + I) = (char) toupper (* (cap + I ));

Return (* env)-> NewStringUTF (env, cap );

}

First, pay attention to the function header. The function receives a jstring type input parameter and outputs a jstring type parameter. Jstring is the data type defined in jni. h and is a string type exclusive to the JNI framework. Because jni. h is introduced in Sample1.h, it is not necessary to introduce it again in Sample1.c.

The second line of the program is to obtain the UTF Encoding input characters from the context of the JNI call and place them in the memory segment pointed to by the pointer str. Row 3 releases the memory. The first line returns the string converted in uppercase. This sentence uses the NewStringUTF () function to convert the string pointer of C language to the JNI jstring type. JNIEnv is also defined in jni. h, representing the context of JNI calls. GetStringUTFChars (), ReleaseStringUTFChars (), and NewStringUTF () are both JNIEnv functions.

2. Send an integer Array
This routine will first try to enable arrays in the JNI framework: the C program returns an array composed of fixed integer numbers to the Java program, and the Java program prints the array.

The source code of the Java program is as follows.

Code List 15-8 routine for calling C Functions on Linux -- Sample2

Public class Sample2

{

Public native int [] intMethod ();

Public static void main (String [] args)

{

System. loadLibrary ("Sample2 ");

Sample2 sample = new Sample2 ();

Int [] nums = sample. intMethod ();

For (int I = 0; I <nums. length; I ++)

System. out. println (nums [I]);

}

}

Sample2.java calls the intMethod () function in libSample2.so (). The source code of Sample2.c is as follows.

Code List 15-9 routine for calling C Functions on Linux -- Sample2.c

# Include <Sample2.h>

JNIEXPORT jintArray JNICALL Java_Sample2_intMethod (JNIEnv * env, jobject obj)

{

Inti = 1;

JintArray array; // defines an array object.

Array = (* env)-> NewIntArray (env, 10 );

For (; I <= 10; I ++)

(* Env)-> SetIntArrayRegion (env, array, I-1, 1, & I );

/* Get the number of elements of the array object */

Int len = (* env)-> GetArrayLength (env, array );

/* Obtain all elements in the array */

Jint * elems = (* env)-> GetIntArrayElements (env, array, 0 );

For (I = 0; I <len; I ++)

Printf ("ELEMENT % d IS % d \ n", I, elems [I]);


Return array;

}

Sample2.c involves two data types related to integer numbers defined by jni. h: jint and jintArray. jint is the integer type exclusive to the JNI framework. The first line of the program opens up a jint array with a length of 10. Then, add the element 1-10 to the array in sequence. Rows 11th to 16th are not a required part of the program. They are used to demonstrate to readers how to use the GetArrayLength () and GetIntArrayElements () functions. The former is to get the length of the array, the latter is to obtain the first address of the array to facilitate the traversal of the array.

3. Pass the String Array
This routine is further deepened in the previous routine: although the array is still transmitted, the base class of the array is replaced by the object data type such as string. The Java program will pass in a string containing Chinese characters to the C program. The C program does not process this string, but opens up a new string array and returns it to the Java program, it also contains two Chinese character strings.

The source code of the Java program is as follows.

Code List 15-10 routine for calling C Functions on Linux -- Sample3

Public class Sample3

{

Public native String [] stringMethod (String text );


Public static void main (String [] args) throws java. io. UnsupportedEncodingException

{

System. loadLibrary ("Sample3 ");

Sample3 sample = new Sample3 ();

String [] texts = sample. stringMethod ("java programming ideology ");

For (int I = 0; I <texts. length; I ++)

{

Texts [I] = new String (texts [I]. getBytes ("ISO8859-1"), "GBK ");

System. out. print (texts [I]);

}

System. out. println ();

}

}

Sample3.java calls the stringMethod () function in libSample3.so (). The source code of Sample3.c is as follows:

Code List 15-11 routine for calling C Functions on Linux -- Sample3.c

# Include <Sample3.h>

# Include <string. h>

# Include <stdlib. h>

# Define ARRAY_LENGTH 5

JNIEXPORT jobjectArray JNICALL Java_Sample3_stringMethod (JNIEnv * env, jobject obj, jstring string)

{

Jclass objClass = (* env)-> FindClass (env, "java/lang/String ");

JobjectArray texts = (* env)-> NewObjectArray (env, (jsize) ARRAY_LENGTH, objClass, 0 );

Jstring jstr;

Char * sa [] = {"Hello,", "world! "," JNI "," very "," fun "};

Int I = 0;

For (; I <ARRAY_LENGTH; I ++)

{

Jstr = (* env)-> NewStringUTF (env, sa [I]);

(* Env)-> SetObjectArrayElement (env, texts, I, jstr); // jstring must be included

}

Return texts;

}

Lines 9th and 10 are worth special attention: the JNI framework does not define a special string array, but uses jobjectArray -- Object array. The base class of the object array is jclass, jclass is a unique type in the JNI framework, which is equivalent to the Class type in Java. In this example, the FindClass () function obtains the java. lang. String type (Class) in the jni context and assigns it to the jclass variable.

In the routine, we define an array of objects with a length of 5, texts, and cyclically add strings in the pre-defined sa array to the 18th rows of the program, of course, the precondition is to use the NewStringUTF () function to convert the C language string to the jstring type.

Another focus of this routine is the question of whether the C program can display the Chinese characters passed to the Java program normally. In the author's test environment, Sample3.c is edited on the Linux platform, and the Chinese characters are input using the GBK-supported input method, java uses the ISO8859_1 character set to store the return characters of JNI calls. Therefore, the code is transcoded and output in line 14th of the "sample 3" routine for Calling C functions on the Linux platform.

4. Passing object arrays
This example demonstrates that the C program transmits an object array to the Java program, and the object array is no longer a string, it is a custom MailInfo object type in Java that contains a topic attribute.

The MailInfo object is defined as follows.

Code List 15-12 routine for calling C Functions on Linux -- MailInfo

Public class MailInfo {

Public String topic;

Public String getTopic ()

{

Return this. topic;

}


Public void setTopic (String topic)

{

This. topic = topic;

}

}

The source code of the Java program is as follows.

Code List 15-13 routine for calling C Functions on Linux-Sample4

Public class Sample4

{

Public native MailInfo [] objectMethod (String text );

Public static void main (String [] args)

{

System. loadLibrary ("Sample4 ");

Sample4 sample = new Sample4 ();

MailInfo [] mails = sample. objectMethod ("Thinking In Java ");

For (int I = 0; I <mails. length; I ++)

System. out. println (mails [I]. topic );

}

}

Sample4.java calls the objectMethod () function in libSample4.so. The source code of Sample4.c is as follows.

Code List 15-14 routine for calling C Functions on Linux-Sample4.c

# Include <Sample4.h>

# Include <string. h>

# Include <stdlib. h>

# Define ARRAY_LENGTH 5

JNIEXPORT jobjectArray JNICALL Java_Sample4_objectMethod (JNIEnv * env, jobject obj, jstring string)

{

Jclass objClass = (* env)-> FindClass (env, "java/lang/Object ");

JobjectArray mails = (* env)-> NewObjectArray (env, (jsize) ARRAY_LENGTH, objClass, 0 );


Jclass objectClass = (* env)-> FindClass (env, "MailInfo ");

JfieldID topicFieldId = (* env)-> GetFieldID (env, objectClass, "topic", "Ljava/lang/String ;");


Int I = 0;

For (; I <ARRAY_LENGTH; I ++)

{

(* Env)-> SetObjectField (env, obj, topicFieldId, string );

(* Env)-> SetObjectArrayElement (env, mails, I, obj );

}


Return mails;

}

The readers of lines 9th and 10 of the program should not be unfamiliar. They have already appeared in the previous example. The difference is that the FindClass () function obtains java in the JNI context. lang. object Type (Class), and use it as the base Class to open up an array of objects with a length of 5, ready to store MailInfo objects.

Rows 12th and 13 of the program are used to create a jfieldID variable. In JNI, the operation object attributes are all carried out through jfieldID. Row 12th first finds the MailInfo type (Class), then obtains its topic Attribute Based on this jclass, and assigns it to the jfieldID variable.

Rows 18th and 19 of the program are used to cyclically Add the jobject object to the object array. The SetObjectField () function is used for the first time. It assigns a value to the jobject attribute, and the value content is the jstring variable value passed in by the Java program. Note that when assigning values to object attributes and placing objects in object arrays, we use the jobject-type environment parameter obj defined in the function header as the intermediary. So far, the two inherent environment input parameters env and obj of the JNI frame are involved.

5. Pass byte []
Source C
Int SmsSend (char * phonenum, char * contnet );
Native local in java
Public native static int SmsSend (byte [] mobileNo, byte [] smContent );
JNIEXPORT jint JNICALL Java_Sample5_objectMethod (JNIEnv * env, jclass jobject, jbyteArray inclueno, jbyteArray smscontent ){
Char * pSmscontent;
// Jsize * theArrayLengthJ = (* env)-> GetArrayLength (env, inclueno );
Jbyte * arrayBody = (* env)-> GetByteArrayElements (env, moblieno, 0 );
Char * pMobileNo = (char *) arrayBody;
Printf ("[% s] \ n, pMobileNo );
// Jsize * theArrayLengthJ = (* env)-> GetArrayLength (env, smscontent );
ArrayBody = (* env)-> GetByteArrayElements (env, smscontent, 0 );
PSmscontent = (char *) arrayBody;
Printf ("[% s] \ n, pSmscontent );
Return SmsSend (pMobileNo, pSmscontent );

Author "jykenan"

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.