JNI AttachNativeThread在Linux上始终失败,返回值为-1

时间:2019-04-21 18:18:23

标签: java c++ java-native-interface jnienv

我正在围绕本机C ++库编写JNI包装器,但是在将本机线程附加到Linux上的JVM时遇到问题。在Windows上一切正常,但是当我在Ubuntu计算机上调用AttachNativeThread()时,它始终返回-1。

这是我获取JNIEnv指针的方式:

, {})

我知道JVM指针不为null,并且代码再次在Windows上完美运行。如果由于某种原因无法在Linux上附加本机线程,那么我总是愿意接受其他选择:我试图实现的目标基本上是Java代码中的回调。在C ++中会发生一个事件,例如打开File的请求,而我需要能够在Java中处理该事件。

更新:我的JVM版本为JNIEnv* Utils::getJNI() { JNIEnv* jni; int getEnvResult = FMODWrapper::jvm->GetEnv((void**) &jni, JNI_VERSION_1_8); if (getEnvResult == JNI_EDETACHED) { JavaVMAttachArgs attachArgs; attachArgs.version = JNI_VERSION_1_8; attachArgs.group = nullptr; std::stringstream newName; newName << "jni-attached-daemon-" << std::this_thread::get_id(); attachArgs.name = (char*) newName.str().c_str(); int attachResult = FMODWrapper::jvm->AttachCurrentThreadAsDaemon(ANDROID_VOIDPP_CAST &jni, &attachArgs); if(attachResult != 0) { std::cerr << "Failed to attach thread! " << attachResult << "(" << newName.str() << ")" << std::endl; } } return jni; } java,这是我用来编译和运行程序的版本。

javac

2 个答案:

答案 0 :(得分:0)

可能您在Linux上的JVM不兼容Java 8。除非您使用某些Java 8 JNI功能,否则没有理由要求JNI_VERSION_1_8。通常,JNI_VERSION_1_6就足够了。

答案 1 :(得分:0)

请参见 JNI Linux segmentation fault 。从Windows切换到Linux时,使用相同的 FMODWrapper 是相同的问题。

根本原因可能是包装器中使用的记录器。如 Lóránt Viktor Gerber 所示,记录器使用对 java / lang / System 的本地引用进行了初始化。如果此记录器某种程度上参与了Utils::getJNI(),它将失败。

代码的另一个可疑部分是将临时名称传递给AttachCurrentThreadAsDaemon()。我会尝试将其设置为 nullptr 以排除任何干扰。

如果以上所有方法均无效,请检查Linux环境中AttachCurrentThreadAsDaemon()(不是作为守护程序)是否仍然失败。