AttachCurrentThread застрял в JNI - PullRequest
       18

AttachCurrentThread застрял в JNI

0 голосов
/ 25 марта 2019

Я пытаюсь понять странное поведение приложения 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;
}
...