I would like to create a Java program to listen for and respond to events captured by a thread in C.
Can someone explain how this can be achieved using JNI, or point me to online tutorials?
我想创建一个Java程序来监听和响应C中线程捕获的事件。有人可以解释如何使用JNI实现这一点,还是指向我的在线教程?
Thank you.
2 个解决方案
#1
2
You can have the native code call a Java method to receive the event. There are several articles on JNI that can help you out, such as How to Call Java functions from C Using JNI.
您可以让本机代码调用Java方法来接收事件。 JNI上有几篇可以帮助你的文章,例如如何使用JNI从C调用Java函数。
#2
2
The JNI specification is required reading if you want to do any sort of JNI-programming.
如果要进行任何类型的JNI编程,则需要读取JNI规范。
There are two scenarios when calling Java code from C. In the first case, the Java program calls a native method, passing control to C. The C function receives as its first argument a JNIEnv
pointer which is the primary handle used to access the JNI. A typical call from Java to C looks like this:
从C调用Java代码有两种情况。在第一种情况下,Java程序调用本机方法,将控制传递给C.C函数接收JNIEnv指针作为其第一个参数,该指针是用于访问JNI的主要句柄。 。从Java到C的典型调用如下所示:
jenv->CallStaticMethod(jenv, cls, ...);
(Note that in C++, the calls are proper methods, so you don't need to pass jenv
as the first argument.) This is rather straightforward; Java calls C which calls back into Java.
(注意,在C ++中,调用是正确的方法,因此您不需要将jenv作为第一个参数传递。)这是相当简单的; Java调用C调用回调为Java。
The second case is a little more complex, and has to be used when you have C-code which needs to make a "spontaneous" call into Java, i.e. not as a result of that code first being called from Java. This is typically the case where you have a native thread generating events (as in your case). You then need to use an part of the JNI referred to as the Invocation API. This API is used in two steps: first you request a reference to the JVM you want to call (some JVM implementations support multiple JVMs in the same process), and the second step is to request a JNIEnv
pointer in order to make calls into the JVM.
第二种情况稍微复杂一些,当你有C代码需要对Java进行“自发”调用时,必须使用它,即不是因为首先从Java调用该代码。通常情况下,您有一个本机线程生成事件(如您的情况)。然后,您需要使用称为Invocation API的JNI的一部分。此API分两步使用:首先请求对要调用的JVM的引用(某些JVM实现在同一进程中支持多个JVM),第二步是请求JNIEnv指针以便调用JVM。
In order to get a JNIEnv
pointer to make calls into the JVM, the native thread needs to "attach" itself to the JVM. This is done in order to make the JVM "aware" of the thread, and after attaching a thread to the JVM, the thread can be thought of as being any other Java thread (in fact, I'm not sure that there are any real differences). If you inspect the JVM's threads in a debugger, the native thread will show up as any other thread. Note that you can mark the native thread as being a daemon thread, so when the JVM exits, the thread will be killed.
为了获得JNIEnv指针来调用JVM,本机线程需要将自身“附加”到JVM。这样做是为了让JVM“知道”线程,并且在将线程附加到JVM之后,线程可以被认为是任何其他Java线程(事实上,我不确定是否有任何线程)真实的差异)。如果在调试器中检查JVM的线程,则本机线程将显示为任何其他线程。请注意,您可以将本机线程标记为守护程序线程,因此当JVM退出时,该线程将被终止。
Note, however, that you will need to take proper precautions when doing things in a Unix signal handler. I'd recommend not calling into Java directly from a signal handler.
但请注意,在Unix信号处理程序中执行操作时需要采取适当的预防措施。我建议不要直接从信号处理程序调用Java。
#1
2
You can have the native code call a Java method to receive the event. There are several articles on JNI that can help you out, such as How to Call Java functions from C Using JNI.
您可以让本机代码调用Java方法来接收事件。 JNI上有几篇可以帮助你的文章,例如如何使用JNI从C调用Java函数。
#2
2
The JNI specification is required reading if you want to do any sort of JNI-programming.
如果要进行任何类型的JNI编程,则需要读取JNI规范。
There are two scenarios when calling Java code from C. In the first case, the Java program calls a native method, passing control to C. The C function receives as its first argument a JNIEnv
pointer which is the primary handle used to access the JNI. A typical call from Java to C looks like this:
从C调用Java代码有两种情况。在第一种情况下,Java程序调用本机方法,将控制传递给C.C函数接收JNIEnv指针作为其第一个参数,该指针是用于访问JNI的主要句柄。 。从Java到C的典型调用如下所示:
jenv->CallStaticMethod(jenv, cls, ...);
(Note that in C++, the calls are proper methods, so you don't need to pass jenv
as the first argument.) This is rather straightforward; Java calls C which calls back into Java.
(注意,在C ++中,调用是正确的方法,因此您不需要将jenv作为第一个参数传递。)这是相当简单的; Java调用C调用回调为Java。
The second case is a little more complex, and has to be used when you have C-code which needs to make a "spontaneous" call into Java, i.e. not as a result of that code first being called from Java. This is typically the case where you have a native thread generating events (as in your case). You then need to use an part of the JNI referred to as the Invocation API. This API is used in two steps: first you request a reference to the JVM you want to call (some JVM implementations support multiple JVMs in the same process), and the second step is to request a JNIEnv
pointer in order to make calls into the JVM.
第二种情况稍微复杂一些,当你有C代码需要对Java进行“自发”调用时,必须使用它,即不是因为首先从Java调用该代码。通常情况下,您有一个本机线程生成事件(如您的情况)。然后,您需要使用称为Invocation API的JNI的一部分。此API分两步使用:首先请求对要调用的JVM的引用(某些JVM实现在同一进程中支持多个JVM),第二步是请求JNIEnv指针以便调用JVM。
In order to get a JNIEnv
pointer to make calls into the JVM, the native thread needs to "attach" itself to the JVM. This is done in order to make the JVM "aware" of the thread, and after attaching a thread to the JVM, the thread can be thought of as being any other Java thread (in fact, I'm not sure that there are any real differences). If you inspect the JVM's threads in a debugger, the native thread will show up as any other thread. Note that you can mark the native thread as being a daemon thread, so when the JVM exits, the thread will be killed.
为了获得JNIEnv指针来调用JVM,本机线程需要将自身“附加”到JVM。这样做是为了让JVM“知道”线程,并且在将线程附加到JVM之后,线程可以被认为是任何其他Java线程(事实上,我不确定是否有任何线程)真实的差异)。如果在调试器中检查JVM的线程,则本机线程将显示为任何其他线程。请注意,您可以将本机线程标记为守护程序线程,因此当JVM退出时,该线程将被终止。
Note, however, that you will need to take proper precautions when doing things in a Unix signal handler. I'd recommend not calling into Java directly from a signal handler.
但请注意,在Unix信号处理程序中执行操作时需要采取适当的预防措施。我建议不要直接从信号处理程序调用Java。