JNI getObjectClass crashes VM
JNI getObjectClass crashes VM
我正在尝试制作C 确实通过JNI登录到Java侧的事情。
到目前为止,我有一个本地设置者:
public native void setLogger(Logger logger);
我在C 中实现:
void __stdcall Java_setLogger(JNIEnv* env, jobject, jobject loggerInstance)
{
logger = Logger(env, &loggerInstance);
}
Logger类的构造函数如下:
Logger::Logger(JNIEnv* env, jobject* loggerInstance)
{
this->env = env;
this->loggerInstance = *loggerInstance;
}
当我尝试通过提供的Logger实例(从Java(在JNI上调用JAVA方法时,它会崩溃VM。我不确定为什么,因为这是从其他stackoverflow问题拼凑在一起的。
void Logger::debug(const std::string code, const std::string message) const
{
std::cout << "debug!" << std::endl; //for debugging purposes
jclass loggerClass = env->GetObjectClass(loggerInstance);
std::cout << "class retrieved" << std::endl; //for debugging purposes
if (loggerClass == NULL)
{
std::cout << "logger class null" << std::endl;
return;
}
jmethodID debugMethod = env->GetMethodID(loggerClass, "debug", "(Ljava/lang/String;Ljava/lang/String;)V");
std::cout << "method retrieved" << std::endl; //for debugging purposes
if (debugMethod == NULL)
{
std::cout << "debug method null" << std::endl;
return;
}
env->CallVoidMethod(loggerInstance, debugMethod, code, message);
}
控制台输出:
debug!
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000067dbef23, pid=6812, tid=0x0000000000003354
Java侧记录器上的调试方法是:
public final void debug(String code, String message) {
...
}
最后,产生的错误日志文件提到:
Internal exceptions (2 events):
Event: 0.041 Thread 0x0000000000d9e800 Exception <a 'java/lang/NoSuchMethodError': Method sun.misc.Unsafe.defineClass(Ljava/lang/String;[BII)Ljava/lang/Class; name or signature does not match> (0x0000000780987ca8) thrown at [C:reworkspace8-2-build-windows-amd64-cygwinjdk8u1218372hotspot
Event: 0.041 Thread 0x0000000000d9e800 Exception <a 'java/lang/NoSuchMethodError': Method sun.misc.Unsafe.prefetchRead(Ljava/lang/Object;J)V name or signature does not match> (0x0000000780987f90) thrown at [C:reworkspace8-2-build-windows-amd64-cygwinjdk8u1218372hotspotsrcsharevmprims
也许我应该提到爪哇一侧不是爪哇。但这是kotlin。
更新(已解决(:
所以,我按照下面的答案说,但后来我注意到我什至没有参加"调试!"cout。我很困惑,但后来我意识到在灾难中,我总是致电env->deleteGlobalRef(..)
,并且我有一个必要的默认构造函数(没有初始化的构建器(可以声明Logger logger;
并以后在C 中初始化它。
在删除全局参考求解所有内容之前,只需添加if(loggerInstance != NULL)
即可。这是因为当我分配一个新值时,C (Visual C (调用灾难,并且在将Logger logger;
放置在某个地方时实际上分配了一个新实例(无论如何从我的观察值中(。
垃圾收集器可以在Java侧移动对象,因此,如果您这样保存logger对象,则可以在JNI调用之间移动它,因此,当您尝试使用时在GetObjectClass
中,指针可能正在悬空。
存储指向Java对象的指针的安全方法是使用NewGlobalRef
,该CC_7在对象上创建 pin :
this->loggerInstance = env->NewGlobalRef(*loggerInstance);
使用它完成后,请确保用DeleteGlobalRef
再次删除它(请应用5的规则(。
我还将指出您的最后一个电话:env->CallVoidMethod(loggerInstance, debugMethod, code, message);
将行不通。从std::string
到java.lang.String
,没有自动召集。您可以致电NewStringUTF
创建Java字符串,然后通过。
我认为您必须使用jString而不是C 字符串本身
void Logger::debug(const std::string code, const std::string message) const
{
std::cout << "debug!" << std::endl; //for debugging purposes
jclass loggerClass = env->GetObjectClass(loggerInstance);
std::cout << "class retrieved" << std::endl; //for debugging purposes
if (loggerClass == NULL)
{
std::cout << "logger class null" << std::endl;
return;
}
jstring javMessage = env->NewStringUTF((const char* )message.c_str());
jstring javCode = env->NewStringUTF((const char* )code.c_str());
jmethodID debugMethod = env->GetMethodID(loggerClass, "debug", "(Ljava/lang/String;Ljava/lang/String;)V");
std::cout << "method retrieved" << std::endl; //for debugging purposes
if (debugMethod == NULL)
{
std::cout << "debug method null" << std::endl;
return;
}
env->CallVoidMethod(loggerInstance, debugMethod, javCode, javMessage);
}
- Linux VM(重型多线程应用程序)的性能改进
- JNI getObjectClass crashes VM
- dll + boost + VS2015 + WinXP == crashes
- JNI 失败并显示'Error occurred during initialization of VM'
- 创建堆栈VM时的分割故障
- 从外部 VM 复制特定数据的最佳方法是什么?
- Cocos2d Firebase Admob crashes
- C++"Hello World"在VM上崩溃
- 如何从VM调用本机函数
- Directx11 - DeviceContext::ClearRenderTargetView crashes
- 调试 VM 中的进程
- OpenCV Harris Corner Detection crashes
- C++ Linux VM 上的 Android 开发
- Eclipse C/C++:外部库的交叉编译链接器错误:Ubuntu VM amd64 to Ubuntu armhf
- 在 CMS ActiveMQ 中使用 VM
- 获取 Java VM 引用,从C++和并发创建 Java 对象
- 是否有可以执行 OpenGL 3+ 的 VM?VirtualBox和VMware没有
- Qt Program Crashes aftes QTextEdit 通过 QTextCursor 进行修改
- OpenGL glBufferStorage crashes
- vector.push_back() crashes