Jni debugging 3 (thread debugging env variable issues), jnienv

Source: Internet
Author: User

Jni debugging 3 (thread debugging env variable issues), jnienv

Cause of thread crash in jni layer debugging

1. Cause of crash:

In the thread function in the jni layer, if you add a function that calls env, it will crash. 2. solution 1: ① (independence) JNIEnv is a thread-related variable, that is, thread A has A JNIEnv variable, and thread B also has A JNIEnv variable. Due to thread-related, thread A cannot use the JNIEnv struct variable of thread B. How can we ensure the independence of JNIEnv for each thread? 

A java object uses JNI to call a send () function in the DLL to send messages to the server. A message is returned immediately after the server message arrives, at the same time, the JNI interface pointer JNIEnv * env (Virtual Machine environment pointer) and jobject obj are saved in the DLL variables. after a period of time, the message receiving thread in the DLL receives the message sent from the server and tries to call the method of the previous java object (equivalent to the JAVA callback method) through the stored env and obj) in this case, the program will suddenly exit (crash ).

That is, the foreground JAVA thread sends messages, and the background thread processes messages, which belong to two different threads,The same JNIEnv variable cannot be used. here we can use a mechanism: Use the global JavaVM * pointer to get the JNIEnv * pointer of the current thread.Similar to the principle that two threads in C ++ use TLS for local storage.


Specific Method:

Obtain the global JavaVM variable:

/* Our VM */
JavaVM * g_vm;

Env-> GetJavaVM (& g_vm); // to get the JavaVM pointer. After obtaining the pointer, save the JavaVM. (Transcription)

 

② (Public) first understand TLS(Thread-local storage)

A thread is a unit of execution. Multiple Threads in a process share the address space of the process. A thread generally has its own stack, however, if you want to implement a global variable to get different values between different threads, it will not be affected. One way is to adopt the thread synchronization mechanism, such as adding a critical section or mutex to the reading and writing of this variable. However, this is at the cost of sacrifice efficiency. Can it be left unlocked? This is what Thread Local Storage does.


Solve the above two problems: 1. First define global variables
Namespace android {static JavaVM * gJavaVM = NULL; // defines a global Java VM reference object static jobject gJavaObj = NULL; // defines a global Java object, Class object for the java Layer
......

2. Second, it is defined in the function that calls a thread: (ensure that the resources of the thread in the process are public. The two statements are to pass the parameters to the opened thread)

JNIEXPORT void JNICALL Java_Test_setEnev (JNIEnv * env, jobject obj) {env-> GetJavaVM (& gs_jvm ); // save it to the global variable. JVM // it is impossible to directly assign the value of obj to the global variable in DLL. The following function should be called: gs_object = env-> NewGlobalRef (obj ); HANDLE ht = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) ThreadFun, 0, NULL, NULL );}

 

3. Reference in the thread function: (ensure that the thread function corresponds to env and class)
Void WINAPI ThreadFun (PVOID argv) // The JNI thread callback method {JNIEnv * env; gs_jvm-> AttachCurrentThread (void **) & env, NULL ); // according to the preceding statements, the variables are retrieved from the above function and the jclass cls = env-> GetObjectClass (gs_object) is used in this thread ); // obtain the Global Object jfieldID fieldPtr = env-> GetFieldID (cls, "value", "I") in the JAVA thread; // obtain the JAVA object while (1) {Sleep (100); // here, the attribute value of the JAVA object is changed (callback JAVA) env-> SetIntField (gs_object, fieldPtr, (jint) gs_ I ++ );}}

3. We can see some program information about jni on the Internet (* env)->;

In linux. this structure cannot be found when "env->" is used for compiling in the c file. You must use "(* env)->" or change it. cpp file, which is compiled in c ++.

 

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

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.