これは私の最初の投稿ですので、理解を示してください。私はいくつかのJavaコードを持っており、いくつかのネイティブコードを持っています。
現時点では、Javaの部分はそれほど面白くないので、c++の部分にスキップします。
//some more trivial includes
#include <signal.h>
//these are global variables
jclass GLOBAL_CLASS;
JNIEnv * GLOBAL_ENV;
jobject GLOBAL_OBJECT;
jmethodID METHOD_ID;
void sigproc(int signo)
{
if (signo == SIGINT)
{
signal(SIGINT, sigproc);
//if Ctrl-c is pressed I want to call a method within my java class
//since I can pass only int to this function
//I've decided to use global variables
GLOBAL_ENV->CallVoidMethod(GLOBAL_OBJECT, METHOD_ID);
exit(0);
}
}
JNIEXPORT void JNICALL Java_intern_Work_readFromFile
(JNIEnv *env, jobject obj, jobjectArray arr)
{
/*define a signal trap! */
signal(SIGINT, sigproc);
//sigproc(SIGINT);
/*initialize the global variables */
GLOBAL_ENV = env;
GLOBAL_OBJECT = obj;
GLOBAL_CLASS = env->GetObjectClass(obj);
//method id is the same so it's better to cache it
//at the beginning
jmethodID mid = env->GetMethodID(GLOBAL_CLASS,
"nativeListener",
"(Ljava/lang/String;)V");
METHOD_ID = GLOBAL_ENV->GetMethodID(GLOBAL_CLASS,
"closeEverything", "()V");
//let's say I have a while(true) block just below
//and some more work is done.
}
この関数は、MainClassの開始時にトリガーされます。削除するとプログラムは正しく実行されます
GLOBAL_ENV->CallVoidMethod(GLOBAL_OBJECT, METHOD_ID);
しかし、問題は、動的に割り当てられたメモリを解放する予定であるため、それが必要なことです+クラスのこの関数を呼び出す必要があります。(言い換えると、ターミナルでctrl-cを押すと、JVMがSIGSEGVでチェッシュすると表示されます)
カーネルからシグナルが渡されたときに実際に何が起こっているのか、実際には理解していないようです。私のグローバル変数GLOBAL_ENVは、まだ使用できる正しいポインターですか?
誰かが私の問題を解決するためのエレガントな方法を教えてもらえますか?または、どんなガイダンスも大歓迎です!どんな説明でも...なんでも。前もって感謝します!
次に、JVMクラッシュコードのサンプルを示します。
A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f9974cfc021, pid=7099, tid=140297087112960
#
# JRE version: 6.0_24-b24
# Java VM: OpenJDK 64-Bit Server VM (20.0-b12 mixed mode linux-amd64 compressed oops)
# Derivative: IcedTea6 1.11.4
# Distribution: Ubuntu 12.04 LTS, package 6b24-1.11.4-1ubuntu0.12.04.1
# Problematic frame:
# V [libjvm.so+0x617021] methodOopDesc::result_type() const+0x31