Detailed description of JNI usage in Java Article 4: Creating Java objects and String objects in C/C ++ and operating methods on strings

Source: Internet
Author: User

First, let's take a look at how to create a Java object in C/C ++: There are two methods in JNIEnv to create a Java object:

Method 1:

Jobject NewObject (jclass clazz, jmethodID methodID ,....):

Parameter description:

Clazz: This is very simple. It is the Class Object of the Java object to be created.

MethodID: This is the ID for passing a method. Think about how to execute a Java object when it is created? Right. That's the constructor.

The third parameter is the parameter value that the constructor needs to pass in (the default constructor does not need to pass in this parameter)

Therefore, before creating a Java object, we need to obtain the class Object of the object, then obtain the constructor of the object, and obtain the id of the method, the signature of the method is required. Because the constructor does not return a value, we thinkClass default constructor return value type signature is always "() V" (because the default constructor does not have parameters), the method name is always" "

Example: Construct a Date object in Java in C ++ and call its getTime () method to print the current time

The code in Java does not need to be changed. It is mainly rewritten in C ++ code:

 

[Cpp] 
  1. # Include
  2. # Include com_jni_demo_JNIDemo.h
  3.  
  4. JNIEXPORT void JNICALL Java_com_jni_demo_JNIDemo_sayHello (JNIEnv * env, jobject obj)
  5. {
  6. // Obtain the Class Object of the Date object in Java
  7. Jclass clazz_date = env-> FindClass (java/util/Date );
  8. // Obtain the constructor id
  9. JmethodID mid_date = env-> GetMethodID (clazz_date, , () V );
  10. // Generate a Date object
  11. Jobject now = env-> NewObject (clazz_date, mid_date );
  12. // Obtain the id of the getTime method in the Date object
  13. JmethodID mid_date_getTime = env-> GetMethodID (clazz_date, getTime, () J );
  14. // Call the getTime method to return the time
  15. Jlong time = env-> CallLongMethod (now, mid_date_getTime );
  16. // Print the time. Note that cout output cannot be used, because cout does not overload the output of _ int64. printf (% I64d, time );
  17. Printf (% I64d, time );
  18. }

     

    Compile it into a. dll file and run the following results in Eclipse:

    The output time is not formatted.

     

    Method 2:

    Create an object: AllocObject

    You can use the AllocObject function to create a Java object based on the passed-In jclass, but its status is not initialized. Before it is an object, you must use CallNonvirtualVoidMethod to call the jclass constructor, in this wayConstructor call can be delayed, This part is rarely used, just a simple description:

    The code in Java is not modified. The C ++ code is changed to the following:

     

    [Cpp]View plaincopy
    1. # Include
    2. # Include com_jni_demo_JNIDemo.h
    3.  
    4. JNIEXPORT void JNICALL Java_com_jni_demo_JNIDemo_sayHello (JNIEnv * env, jobject obj)
    5. {
    6. // Obtain the Date object in java
    7. Jclass clazz_date = env-> FindClass (java/util/Date );
    8. JmethodID methodID_str = env-> GetMethodID (clazz_date, , () V );
    9. Jobject now = env-> AllocObject (clazz_date );
    10. // Call the constructor
    11. Env-> CallNonvirtualVoidMethod (now, clazz_date, methodID_str );
    12. // Obtain the id of the getTime method in the Date object
    13. JmethodID mid_date_getTime = env-> GetMethodID (clazz_date, getTime, () J );
    14. // Call the getTime method to return the time
    15. Jlong time = env-> CallLongMethod (now, mid_date_getTime );
    16. // Print the time. Note that cout output cannot be used, because cout does not overload the output of _ int64. printf (% I64d, time );
    17. Printf (% I64d, time );
    18. } This method is rarely used!

       

      Next, let's take a look at how to operate strings in Java in C/C ++.

      First, let's take a look at some C ++ methods in JNIEnv:

      1. Get the length of the string:

      Parameter: j_msg: A jstring object

      Env-> GetStringLength (jstring j_msg );

      2. Copy the jstring object to the const jchar * pointer string

      Parameter: j_msg: A jstring object. start indicates the start position of the string to be copied, end indicates the end position of the string to be copied, and jstr indicates the target pointer string.

      Env-> GetStringRegion (jstring j_msg, int start, int end, const jchar * jstr );

      3. Generate a jstring object

      Parameter: jstr is a string pointer and size is the string length.

      This method can be considered to convert the string pointer jstr into a string object jstring

      Env-> NewString (const jchar * jstr, int size );

      4. Convert the jstring object to const jchar * string pointer

      Parameter: j_msg is a string object.

      Env-> GetStringChars (jstring j_msg, NULL );

      The corresponding method for releasing the memory pointer is as follows:

      Parameter: j_msg is a jstring object, and jstr is a string pointer.

      ReleaseStringChars (jstring j_msg, const jchar * jstr );

      5. Convert the jstring object to const jchar * string pointer

      Parameter: j_msg is a string object.

      This method is the same as the fourth method.

      Env-> GetStringCritical (jstring j_msg, NULL );

      The corresponding method for releasing the memory pointer is as follows:

      Env-> ReleaseStringCritical (jstring j_msg, const jchar * jstr );

       

      Let's take a look at the example below: Define a String attribute in Java, enter a value in the console, and then define a local method callCppFunction. In C ++, the implementation of this method is: obtain this string attribute in Java, perform reverse operations on it, and then output it in Java:

      Let's take a look at the code in Java:

      [Java]
      1. Package com. jni. demo;
      2.  
      3. Import java. io. BufferedReader;
      4. Import java. io. InputStreamReader;
      5.  
      6. Public class JNIDemo {
      7.  
      8. // Define a local method
      9. Public native void callCppFunction ();
      10. // Define a String attribute
      11. Public String msg = null;
      12. Public static void main (String [] args) throws Exception {
      13. // Call the dynamic link library
      14. System. loadLibrary (JNIDemo );
      15. // Obtain the value from the console
      16. BufferedReader reader = new BufferedReader (new InputStreamReader (System. in ));
      17. String str = reader. readLine ();
      18. JNIDemo jniDemo = new JNIDemo ();
      19. JniDemo. msg = str;
      20. JniDemo. callCppFunction ();
      21. System. out. println (jniDemo. msg );
      22.  
      23. }
      24.  
      25. } Let's take a look at the C ++ code:[Cpp]View plaincopy
        1. # Include
        2. # Define decom_jni_demo_jnidemo.h
        3. # Includewindows. h
        4. # Include
        5. # Include
        6. Using namespace std;
        7.  
        8. JNIEXPORT void JNICALL Java_com_jni_demo_JNIDemo_callCppFunction (JNIEnv * env, jobject obj)
        9. {
        10. // Obtain the attributes in java: msg
        11. JfieldID fid_msg = env-> GetFieldID (env-> GetObjectClass (obj), msg, Ljava/lang/String ;);
        12. // Get the object of the msg attribute
        13. Jstring j_msg = (jstring) env-> GetObjectField (obj, fid_msg );
        14.  
        15. /** Method 1: START */
        16. /*
        17. // Obtain the string pointer
        18. Const jchar * jstr = env-> GetStringChars (j_msg, NULL );
        19. // Convert to a wide string
        20. Wstring wstr (const wchar_t *) jstr );
        21. // Release the pointer
        22. Env-> ReleaseStringChars (j_msg, jstr );
        23. */
        24. /** First method END */
        25.  
        26. /** Method 2 START */
        27. /*
        28. // Obtain the string pointer
        29. Const jchar * jstr = env-> GetStringCritical (j_msg, NULL );
        30. // Convert to a wide string
        31. Wstring wstr (const wchar_t *) jstr );
        32. // Release the pointer
        33. Env-> ReleaseStringCritical (j_msg, jstr );
        34. */
        35. /** Method 2 END */
        36.  
        37. /** Method 3: START */
        38. // Obtain the length of the string
        39. Jsize len = env-> GetStringLength (j_msg );
        40. // Generate a string pointer with the length of len
        41. Jchar * jstr = new jchar [len + 1];
        42. // The string in C ++ ends with '', otherwise unexpected characters will be output
        43. Jstr [len] = l '';
        44. // Copy the string j_msg to jstr.
        45. Env-> GetStringRegion (j_msg, 0, len, jstr );
        46. // Convert to a wide string
        47. Wstring wstr (const wchar_t *) jstr );
        48. // Release the pointer
        49. Delete [] jstr;
        50. /** Method 3 END */
        51.  
        52. // Reverse the string
        53. Reverse (wstr. begin (), wstr. end ());
        54. // Obtain the new string in reverse order
        55. Jstring j_new_str = env-> NewString (const jchar *) wstr. c_str (), (jint) wstr. size ());
        56. // Set the new string to the variable
        57. Env-> SetObjectField (obj, fid_msg, j_new_str );
        58. } Three methods are used to implement the function. Note that another method is to convert const jchar * To wstring, because the reverse method accepts the wstring parameter. The running result in Eclipse is as follows:

           

          Here we will talk about the content of this article, and the content later will be more exciting!

           

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.