The data interaction between Java and C + +-----JNI drip

Source: Internet
Author: User

Chih, quiet and far away

A Diamond is just a piece of coal the did well under pressure.

Data interaction between Java and C + +-----JNI drip "Turn"

The recent project to make a Tiemsten database uses JNI technology. In this project, we use Java to write the interface and business logic, in C language to write database ODBC access. There is nothing difficult about simple ODBC, but data transfer between Java and C is a tricky thing to do. There are several cases where data is passed between Java and C, where Java passes the object type to C, C returns the object type to Java, and C calls the Java class. Here are a few examples of how to classify.

1. Java passes basic data types to C

For basic data types, Java and C correspond to each other, so they can be used directly. The correspondence between them is;

------------------------------------------------------------------------

Java type Local type byte (bit)

-------------------------------------------------------------------------
  
Boolean Jboolean 8, unsigned
BYTE Jbyte 8
Char Jchar, unsigned
Short Jshort 16
int Jint 32
Long Jlong 64
Float Jfloat 32
Double Jdouble 64
void void N/A

------------------------------------------------------------------------

2.java passing object types to C

For Java to pass in the Java object model, c to load the Java class prototype, based on the creation of the corresponding C object, get the ID of the Java object method, and then call the Java object method. For example, there is a Java class customer object passed to the C program as a JNI parameter, and the customer has the method string GetName ().

Jniexport Jobject Jnicall Java_com_oracle_estt_sc_db_impl_scqueryodbc__1getcustomer
(JNIEnv *env, Jobject, Jobject customer) {

Jmethodid Methodid;
Get a handle to the Customer object
Jclass Cls_objclass=env->getobjectclass (customer);
Gets the ID of the specific method getname in the Customer object
Methodid=env->getmethodid (Cls_objclass, "GetName", "() ljava/lang/string;");
Call a specific method of the Customer object GetName
Jstring js_name= (jstring) Env->callobjectmethod (customer,methodid,null);

...

}

3.c returning object Types to Java

In the C program, you first create the Java object that you want to return, get the ID of each property, assign a value to each property, and finally return. An example of this is the customer object, which has a property value such as name, which needs to be returned after assigning a value to each property in the C program.

Jniexport Jobject Jnicall Java_com_oracle_estt_sc_db_impl_scqueryodbc__1getcustomer
(JNIEnv *env, Jobject, Jobject customer) {

......

The Java customer class is found, and if it fails, the program returns
Jclass clazz = Env->findclass ("Com/oracle/estt/sc/busi/customer");
if (Clazz = = 0)
return 0;
allocating memory for new Java class object obj
Jobject obj = Env->allocobject (clazz);
Discovers the properties in the class, and if it fails, the program returns
Jfieldid fid_id = Env->getfieldid (Clazz, "CustomerID", "I");
if (fid_id = = 0)
return 0;
Jfieldid fid_name = Env->getfieldid (clazz, "name", "ljava/lang/string;");
if (Fid_name = = 0)
return 0;
......

Env->setintfield (obj, fid_id, 1
Env->setobjectfield (obj, Fid_name, jname);

......

return obj;

}

4.C passing an array containing Java objects to Java

In this case, get the size of the array, then take the object in the array, get the object's property value or call the object's method, will get the value into the local array, and then the flexibility to use the data. For example, Java passes an array containing multiple customer objects to C, and in c the decomposition of this array is stored in a local temporary array.

jniexport void Jnicall JAVA_COM_ORACLE_ESTT_SC_DB_IMPL_SCINSERTODBC__1INSERTCUSTOMEREQUEST___3LCOM_ORACLE_ESTT_SC _busi_customerrequest_2
(JNIEnv *env, Jobject, Jobjectarray OA) {

......

Declaring Customerrequest objects
Jobject O_customer;

int i;
Jmethodid Methodid;
Jint Size=env->getarraylength (OA);

_tmp_bind[0]= (char *) malloc (size*sizeof (int));
_tmp_bind[1]= (char *) malloc (size*sizeof (char) * (20 + 1));

...

Copy the data from the input array into a temporary array
for (i=0;i<size;i++) {
Get the Customerrequest object from the array
O_request=env->getobjectarrayelement (Oa,i);
Get a handle to a Customerrequest object
Jclass Cls_objclass=env->getobjectclass (o_request);

Gets the ID of the specific method Getcustomerid the Customerrequest object
Methodid=env->getmethodid (Cls_objclass, "Getcustomerid", "() I");
Call a specific method of the Customerrequest object Getcustomerid
Int_customerid=env->callintmethod (O_request,methodid,null);
Gets the ID of the specific method Gettelnum in the Customerrequest object
Methodid=env->getmethodid (Cls_objclass, "Gettelnum", "() ljava/lang/string;");
Call a specific method of the Customerrequest object Gettelnum
Str_telnum= (jstring) Env->callobjectmethod (o_request,methodid,null);

...

Copy the user ID to a temporary array
memcpy (_tmp_bind[0]+i*sizeof (int), &int_customerid,sizeof (int));

Copy the phone number to a temporary array, if the phone number string is too long, the error returns
if (sizeof (char) *strlen (Chr_tel) <=sizeof (char) * (20 + 1)) {
memcpy (_tmp_bind[1]+i*sizeof (char) * (20+1), Chr_tel,strlen (Chr_tel) +1);
}else{
printf ("%s too long!\n", Chr_tel);
Return
}

...

}

...

}

5.C returns an array to Java

The array is created first, the Java object is loaded, the properties of each Java object are assigned, added to the array, and the array is returned. The following example:

Jniexport Jobjectarray Jnicall Java_com_oracle_estt_sc_db_impl_scqueryodbc__1getcustomerrequest
(JNIEnv *env, Jobject, Jint customerid) {

......

Declares the Objectarray that holds the results of the query
Jobjectarray Jo_array = Env->newobjectarray (Max_line,env->findclass ("com/oracle/estt/sc/busi/  Customerrequest "), 0); Jobject obj;
Discover the Java Customerrequest class, and if it fails, the program returns
Jclass clazz = Env->findclass ("Com/oracle/estt/sc/busi/customerrequest");
if (Clazz = = 0)
return 0;

while (rc = SQLFetch (hstmt)) = = Sql_success | | rc = = sql_success_with_info) {

obj = Env->allocobject (clazz);

Jfieldid Fid_customerid = Env->getfieldid (Clazz, "CustomerID", "I");
if (Fid_customerid = = 0)
return 0;

Jfieldid fid_priority = Env->getfieldid (Clazz, "priority", "I");
if (fid_priority = = 0)
return 0;

...

Env->setintfield (obj, Fid_customerid, Col_customerid);

Env->setintfield (obj, fid_priority, col_priority);

...

To add an object obj to the objects array
if (j<max_line) {
Env->setobjectarrayelement (Jo_array, J, obj);
}else{
Break
}

}

return jo_array;

}

Conversion of 6.jstring to char*

Jstring cannot be used directly in a C program and needs to be converted to char*. It is important to remember to release the char* after you have finished using it to avoid a memory leak. The following example:

Jniexport Jobjectarray Jnicall java_com_oracle_estt_sc_db_impl_scqueryodbc__1getcustomerrequestbycondition
(JNIEnv *env, jobject, jstring condition, Jint customerid) {

Convert jstring to cha*
char* str_condition= (char*) env->getstringutfchars (Condition,jni_false);

......

Releasing variables
Env->releasestringutfchars (condition,str_condition);

......

}

7.char* conversion into jstring

This conversion is cumbersome, but it is used in database operations. For example, the query from the database is char*, but to assign values to the object properties need to use jstring, this is the need to use this conversion. The following example:

char* col_timestamp= ...;

Load String class
Jclass strclass = Env->findclass ("ljava/lang/string;");
Get method ID
Jmethodid Ctorid = Env->getmethodid (strclass, "<init>", "([bljava/lang/string;) V");

Convert a string to jstring
Bytes_time = Env->newbytearray (strlen (Col_timestamp));
Env->setbytearrayregion (bytes_time, 0, strlen (col_timestamp), (jbyte*) col_timestamp);
Jstring js_time = Env->newstringutf ("Utf-8");

Js_time= (jstring) env->newobject (strclass, Ctorid, Bytes_time, Js_time)

The prototype acquisition method of 8.java class

The Java class prototype, especially its method signature, is used to create Java objects and invoke Java object Methods in C. To do this, type the name command in the same directory as the Java class:

>javap-s-P package path. Java class name

The above points are my two days to write a summary of the JNI program, write to share with you, welcome criticism guidance.

Recommended Information:

Java Native Interface specification. http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/jniTOC.html


The data interaction between Java and C + +-----JNI drip

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.