반응형
비동기 호출에 대한 JNI 인터페이스 포인터 (JNIEnv *)를 얻는 방법
JNI 인터페이스 포인터 (JNIEnv *)는 현재 스레드에서만 유효하다는 것을 배웠습니다. 네이티브 메서드 내에서 새 스레드를 시작했다고 가정합니다. Java 메소드에 비동기식으로 이벤트를 보내는 방법은 무엇입니까? 이 새 스레드는 (JNIEnv *)에 대한 참조를 가질 수 없습니다. (JNIEnv *)에 대한 전역 변수를 저장하면 분명히 작동하지 않습니까?
Java에서 C ++ 로의 JNI를 사용하는 동기 호출 내에서 "환경"은 이미 JVM에 의해 설정되었지만 임의의 C ++ 스레드에서 다른 방향으로 진행되지 않았을 수 있습니다.
따라서 다음 단계를 따라야합니다.
- 다음을 사용하여 JVM 환경 컨텍스트를 확보하십시오.
GetEnv
- 필요한 경우 컨텍스트를 첨부하십시오.
AttachCurrentThread
- 다음을 사용하여 정상적으로 메소드를 호출하십시오.
CallVoidMethod
- 사용하여 분리
DetachCurrentThread
전체 예. 참고 나는 과거에 이것에 대해 내 블로그 에 더 자세히 썼습니다.
void callback(int val) {
JNIEnv * g_env;
// double check it's all ok
int getEnvStat = g_vm->GetEnv((void **)&g_env, JNI_VERSION_1_6);
if (getEnvStat == JNI_EDETACHED) {
std::cout << "GetEnv: not attached" << std::endl;
if (g_vm->AttachCurrentThread((void **) &g_env, NULL) != 0) {
std::cout << "Failed to attach" << std::endl;
}
} else if (getEnvStat == JNI_OK) {
//
} else if (getEnvStat == JNI_EVERSION) {
std::cout << "GetEnv: version not supported" << std::endl;
}
g_env->CallVoidMethod(g_obj, g_mid, val);
if (g_env->ExceptionCheck()) {
g_env->ExceptionDescribe();
}
g_vm->DetachCurrentThread();
}
를 사용하여 JVM ( JavaVM*
)에 대한 포인터를 얻을 수 있습니다 JNIEnv->GetJavaVM
. 해당 포인터를 전역 변수로 안전하게 저장할 수 있습니다. 나중에 새 스레드 AttachCurrentThread
에서 새 스레드를 C / C ++로 만든 경우 JVM에 연결하는 데 사용할 수 있습니다. 또는 GetEnv
JNI가 JNIEnv*
다음을 전달하기 때문에 내가 가정하지 않는 Java 코드로 스레드를 만든 경우 간단히 사용할 수 있습니다. 이 문제는 없을 것입니다.
// JNIEnv* env; (initialized somewhere else)
JavaVM* jvm;
env->GetJavaVM(&jvm);
// now you can store jvm somewhere
// in the new thread:
JNIEnv* myNewEnv;
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_6; // choose your JNI version
args.name = NULL; // you might want to give the java thread a name
args.group = NULL; // you might want to assign the java thread to a ThreadGroup
jvm->AttachCurrentThread((void**)&myNewEnv, &args);
// And now you can use myNewEnv
반응형
'Program Tip' 카테고리의 다른 글
Flask @ app.route에서 Python 콘솔로 인쇄하는 방법 (0) | 2020.11.11 |
---|---|
jinja2 출력을 브라우저 대신 Python으로 파일로 렌더링하는 방법 (0) | 2020.11.10 |
Git이 다른 저장소에서 분기를 가져 오나요? (0) | 2020.11.10 |
Python에서 가져온 모듈의 main ()을 호출 할 수 있습니까? (0) | 2020.11.10 |
Django 1.9에서 syncdb 대신 무엇을 사용해야합니까? (0) | 2020.11.10 |