Мне необходимо делать Callback из С++ DLL в JAVA. Проблема в том, что хочется сделать многопотчный вызов. Т.е. создать глобальные обьекты jobject obj и JNIEnv *env, и уже для них делать вызовы методов из разных потоков, а именно
env->CallVoidMethod(obj, targetMethodId, и т.д.)
Пробелема в том, что сделав env->NewGlobalRef(...) я потом не могу найти ни ID метода, если я сохраняю ID метода загодя, то у меня все ломается на этапе вызова.
Следующий вариант, Java создает поток, запускает функцию, функция крутится в вечном вайле и вызывает методы в этом контексте. Все хоррошо, но если попытаться создать поток и передать туда соответствующие обьекты и хендлы, (прошу заметить, основная функция — поток жива и не вредима, значит и обьекты валидны) то происходит та же фигня что и в первом случае...
Как быть?
P.S. могу перефразировать задачу. Необходимо сделать вызвать метод в JAVA из С++ ф-ии, которая на входе не имеет енвиромента и обьекта (не JNI спецификации)
Здравствуйте, loknalori, Вы писали:
...
L>P.S. могу перефразировать задачу. Необходимо сделать вызвать метод в JAVA из С++ ф-ии, которая на входе не имеет енвиромента и обьекта (не JNI спецификации)
1. Объект запомнить используя NewGlobalRef;
2. Получить JNIEnv можно так:
// jvm, инициировать можно либо через вызов JNI_GetCreatedJavaVMs (если нет JNIEnv), либо, если есть JNIEnv, то GetJavaVM
static JavaVM* vm = 0;
// возвращает JNIEnv для произвольного потока (не важно создан-ли он VM-ой или нет):
class JVMAttachee
{
JNIEnv* env_;
bool detach_;
private:
JVMAttachee(const JVMAttachee&);
JVMAttachee& operator = (const JVMAttachee&);
public:
explicit JVMAttachee(): env_(0), detach_(false)
{
if(vm)
{
vm->GetEnv((void**)&env_, JNI_VERSION_1_2);
if(!env_)
{
if(JNI_OK == vm->AttachCurrentThread((void**)&env_, 0))
{
detach_ = true;
}
}
}
}
~JVMAttachee()
{
if(detach_)
{
vm->DetachCurrentThread();
}
}
JNIEnv*
getEnv()
{
return env_;
}
};
Юзать так:
void foo()
{
JVMAttachee vma;
JNIEnv* env = vma->getEnv();
env->CallVoidFunction(...);
}
Если в приложении потоков не созданных из VM нет, то беспокоиться о AttachCurrentThread особого смысла нет и можно обойтись только GetEnv.
Алексей