Я пытаюсь понять странное поведение приложения JNI. Я запускаю поток из собственной подпрограммы JNI dll (sayHello), которая, в свою очередь, при запуске пытается подключиться к потоку JVM, чтобы получить переменную среды. Однако он считает, что не может этого сделать, если не завершен основной поток. Как так? В приведенном ниже примере (не обращая внимания на утечку памяти потока) подпрограмма потока foo успешно подключится к JVM только после Thread.sleep (5000) в основном потоке; Это почему?
ВЫВОД:
Hello World!!!
Hello World from C++!
Hello FROM FOO
Good Bye World!!!
%%% JNIEnv attached : 00000206FF8E7B40
JAVA CODE
package com.home;
public class Main {
static {
System.loadLibrary("JNITest"); // Load native library hello.dll (Windows) or libhello.so (Unixes)
// at runtime
// This library contains a native method called sayHello()
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
System.out.println("Hello World!!!");
new Main().sayHello();
Thread.sleep(5000);
System.out.println("Good Bye World!!!");
}
// Declare an instance native method sayHello() which receives no parameter and returns void
private native void sayHello();
}
JNI DLL
// JNITest.cpp : Defines the exported functions for the DLL application.
//
#include "com_home_Main.h"
#include "stdafx.h"
#include <iostream>
#include <thread>
static JavaVM *g_jVM = NULL;
using namespace std;
void foo()
{
JNIEnv *jEnv = NULL;
cout << "Hello FROM FOO" << endl;
g_jVM->AttachCurrentThreadAsDaemon((void **)(&jEnv), NULL);
if (jEnv == NULL)
{
std::cout << "\n !!! Failed to attach current thread with JVM !!! \n";
}
else
{
std::cout << "\n %%%\t JNIEnv attached : " << (void *)jEnv;
g_jVM->DetachCurrentThread();
}
}
extern "C"
// Implementation of the native method sayHello()
JNIEXPORT void JNICALL Java_com_home_Main_sayHello(JNIEnv *env, jobject thisObj) {
cout << "Hello World from C++!" << endl;
env->GetJavaVM(&g_jVM);
std::thread *first = new std::thread(foo);
return;
}