在 Linux 上,JNI AttachNativeThread 总是失败,返回值为 -1
JNI AttachNativeThread always fails with -1 return value on Linux
我正在围绕本机C++库编写JNI包装器,但是在将本机线程附加到Linux上的JVM时遇到问题。在Windows上一切正常,但是当我在Ubuntu机器上调用AttachNativeThread((时,它总是返回-1。
这是我获得 JNIEnv 指针的方式:
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;
}
我知道JVM指针不为空,同样,代码在Windows上完美运行。如果由于某种原因无法在 Linux 上附加本机线程,我总是对替代方案持开放态度:我试图实现的目标基本上是回调到我的 Java 代码中。C++中发生了一个事件,例如对文件打开的请求,我需要能够在 Java 中处理它。
更新:我的JVM版本,包括java
和javac
,这是我用来编译和运行程序的版本。
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-8u191-b12-2ubuntu0.18.10.1-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
javac 1.8.0_191
可能你在 Linux 上的 JVM 不兼容 Java 8。没有理由要求JNI_VERSION_1_8除非您使用某些Java 8 JNI功能。通常,JNI_VERSION_1_6就足够了。
请参阅 JNI Linux 分段错误。当从Windows切换到Linux时,同样的FMODWrapper也是如此。
根本原因可能是包装器中使用的记录器。正如Lóránt Viktor Gerber在那里显示的那样,记录器是用对java/lang/System的本地引用初始化的。如果这个记录器以某种方式参与Utils::getJNI()
,它将失败。
代码的另一个可疑部分是将临时名称传递给AttachCurrentThreadAsDaemon()
。我会尝试将其设置为 nullptr 以排除任何干扰。
如果上述所有方法都不起作用,请检查 Linux 环境中是否仍然AttachCurrentThreadAsDaemon()
(不是守护程序(仍然失败。
- 从python中调用C++函数并获取返回值
- 为什么模板类中的对象不能返回值
- 返回值优化:显式移动还是隐式
- lock_guard是否保护返回值
- 调用CreateProcess()并获取字符串的返回值
- 如何使 windows 命令提示符在C++可执行文件上显示返回值?
- 编译器警告:执行到达值返回函数的末尾而不返回值
- 查找 GCD:并非所有控制路径都返回值
- 在 Arduino 上使用 sscanf 会导致与 const char * 不匹配,并且返回值始终相同,尽管输入值不同
- 在 Linux 上,JNI AttachNativeThread 总是失败,返回值为 -1
- GMock 的"WillOnce"和"Return"不会因错误的返回值而失败
- 为什么将boost::move()的返回值分配给非常数引用在C++0x模式下失败,但在C++03模式下有效
- 如果返回值未用于特定类型,则编译失败
- 如果我的C++“新”内存分配失败,如何找出返回值
- Visual Studio - 返回值失败时没有编译错误
- 如果 GCC 4.4.7 上未使用返回值,则强制调用类运算符 == 失败
- C++ Visual Studio Express - 分配返回值失败功能
- 参数扣除失败,返回值有效
- Turtle Mock: MOCK_EXPECT如果被Mock的类方法返回值则失败
- 查找失败时增强string_algo返回值