Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JNI getObjectClass使虚拟机崩溃 我试图做一个C++通过JNI登录到java端的事情。_Java_C++_Java Native Interface - Fatal编程技术网

JNI getObjectClass使虚拟机崩溃 我试图做一个C++通过JNI登录到java端的事情。

JNI getObjectClass使虚拟机崩溃 我试图做一个C++通过JNI登录到java端的事情。,java,c++,java-native-interface,Java,C++,Java Native Interface,到目前为止,我有一个本地setter: 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

到目前为止,我有一个本地setter:

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;
}
当我试图在提供的记录器实例(来自java)上通过JNI调用java方法时,它会使VM崩溃。我不知道为什么,因为这是从其他问题拼凑而成的

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);
}
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:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u121\8372\hotspot\
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:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u121\8372\hotspot\src\share\vm\prims
内部异常(2个事件):
事件:0.041线程0x0000000000d9e800异常(0x0000000780987ca8)在[C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u121\8372\hotspot]引发\
事件:0.041线程0x0000000000d9e800异常(0x0000000780987f90)在[C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u121\8372\hotspot\src\share\vm\prims]抛出
也许我应该提到,Java端在技术上不是Java,而是Kotlin


更新(已解决):

所以,我按照下面的答案做了,但后来我注意到我甚至没有进入“调试”阶段。我非常困惑,但后来我意识到,在我的析构函数中,我总是调用
env->deleteGlobalRef(…)
,并且我有一个必要的默认构造函数(不初始化任何内容)能够声明<代码>日志记录程序;< /C> >并在C++中初始化它。


<>简单地在删除全局REF之前添加<代码>(logRealStuty.null)/Cuff.0,这是因为C++(Visual C++)在分配新值时调用析构函数,并且实际上在放置<代码>日志记录器时分配新的实例;< /代码>某处(从我的观察中)

存储指向Java对象的指针的安全方法是使用在对象上创建pin的:

this->loggerInstance = env->NewGlobalRef(*loggerInstance);
只需确保在使用完后,使用
DeleteGlobalRef
再次删除它(因此应用规则5)



我还将指出您最后的调用:
env->CallVoidMethod(loggerInstance、debugMethod、code、message)从<代码> STD::String 到<代码> java .Lang.String < /Cord>,没有自动编组。您可以调用创建java字符串,然后传递它。

< P>我想您必须使用JString而不是C++字符串本身/p>
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);
}
void Logger::debug(const std::string code,const std::string message)const
{

STD::谢谢,引用的类作品,比如C++中的新的,只是你必须让java知道它,也感谢字符串部分,我有很高的希望,但是我已经预料到了。我在这之后有几个问题,我会用它来更新我的问题!最后一件事,你推荐我总是遵循这个方法来注册吗?如果我想在C++中保存java的东西?@是的,你的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);
}