我正在围绕本机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
答案 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()
(不是作为守护程序)是否仍然失败。