Вызов метода Java на основе объекта задания завершается сбоем (неверная ссылка?)C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Вызов метода Java на основе объекта задания завершается сбоем (неверная ссылка?)

Сообщение Anonymous »

У меня следующая проблема:

в моей Java-программе я вызываю собственную функцию, которая создает объект класса «MyEventReceiver» на C++, позже в этой Java-программе я вызываю собственную функцию, которая вызывает «тестовый» метод этого объекта. В этом «тестовом» методе я хочу вызвать метод объекта Java, который я использовал для вызова второй встроенной функции, но как только я делаю этот вызов, jvm выходит из строя.

Это собственный код, создающий объект MyEventReceiver:

JNIEXPORT jlong JNICALL Java_irr4jEventReceiver_native_1createEventReceiver
(JNIEnv *env, jobject obj){
MyEventReceiver *rec = new MyEventReceiver(env, obj);
return (long)rec;
}


это собственный код, который я использую позже в программе для вызова «тестового» метода в этом объекте:

JNIEXPORT void JNICALL Java_irr4jEventReceiver_native_1testmethode
(JNIEnv *env, jobject obj, jlong ptrrec){
MyEventReceiver *rec = (MyEventReceiver*)ptrrec;
rec->test();
}


а это класс MyEventReceiver:

class MyEventReceiver : public IEventReceiver
{
public:
JNIEnv *myenv;
jobject receiverobj;
jclass SEventclass;
jobject eventobj;
jmethodID cid;

jclass cevrec;
jmethodID meth2;
public:

void test(){

eventobj = myenv->AllocObject(SEventclass);
eventobj = myenv->NewObject(SEventclass, cid);
myenv->CallVoidMethod(receiverobj,meth2,eventobj); //this is the line that causes the crash

}

MyEventReceiver(JNIEnv *env, jobject obj)
{

this->myenv=env;
receiverobj = env->NewGlobalRef(obj);

SEventclass = myenv->FindClass("SEvent");
cid = myenv->GetMethodID(SEventclass,"", "()V");
cevrec = myenv->FindClass("MyEventReceiver");
meth2 =myenv->GetMethodID(cevrec, "OnEvent", "(LSEvent;)V");
//test();
}
};


если я вызываю метод "test" в конце конструктора, он работает... только если я позже сделаю вызов из Java-программы... Я думаю, что это как-то связано с проектом задания "receiverobj"... кажется, через некоторое время он становится недействительным, но я не знаю почему
...Я немного удалил код... удалил часть отладочного кода. "eventobj", который я создаю, в порядке... Я могу вызывать другие методы этого объекта, идентификаторы методов тоже в порядке, просто строка:

myenv->CallVoidMethod(receiverobj,meth2,eventobj);


вызывает проблемы, и я не знаю почему :)

Сообщение о сбое:

#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x67d594f4, pid=5292, tid=2400
#
# JRE version: 7.0_21-b11
# Java VM: Java HotSpot(TM) Client VM (23.21-b01 mixed mode, sharing windows-x86 )
# Problematic frame:
# V [jvm.dll+0xa94f4]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# G:\irr4jjava\irr4j\hs_err_pid5292.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
#


РЕДАКТИРОВАТЬ:

Спасибо за помощь. Я пытался использовать глобальные ссылки и прикрепленный поток, но не смог заставить его работать. Я не уверен, что понял суть прикрепленного потока...

Я изменил первый собственный метод, чтобы создать глобальную ссылку на объект задания и передать ее конструктору:
JavaVM *jvm;

JNIEXPORT jlong JNICALL Java_irr4jEventReceiver_native_1createEventReceiver
(JNIEnv *env, jobject obj){
jobject recobj = env->NewGlobalRef(obj);
env->GetJavaVM(&jvm);
MyEventReceiver *rec = new MyEventReceiver(recobj);
return (long)rec;
}


в классе «MyReceiverObject» я пытаюсь прикрепить поток, но он все равно вылетает:

class MyEventReceiver : public IEventReceiver
{
public:
JNIEnv *myenv;
jobject receiverobj;
jclass SEventclass;
jobject eventobj;
jmethodID cid;
jclass cevrec;
jmethodID meth2;
public:

void test(){

jvm->AttachCurrentThread((void**)&myenv,NULL);

eventobj = myenv->AllocObject(SEventclass); //crash
eventobj = myenv->NewObject(SEventclass, cid);
myenv->CallVoidMethod(receiverobj,meth2,eventobj);
}

MyEventReceiver(jobject obj)
{

jvm->AttachCurrentThread((void**)&myenv,NULL);
receiverobj=obj;

SEventclass = myenv->FindClass("SEvent");
cid = myenv->GetMethodID(SEventclass,"", "()V");
cevrec = myenv->FindClass("MyEventReceiver");
meth2 =myenv->GetMethodID(cevrec, "OnEvent", "(LSEvent;)V");

//test();
}
};


Подробнее здесь: https://stackoverflow.com/questions/167 ... -reference
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»