当前位置: 首页 > 知识库问答 >
问题:

JNI类ID segfault

於意蕴
2023-03-14

我试图在JavaJNI中缓存方法ID和JClass,但是当我使用缓存的值时,我遇到了EXE_BAD_ACCESS。当我请求与使用它们的html" target="_blank">函数内联的值时,错误消失了。我发现我需要使用全局引用,但是这并没有解决分段错误。

jni缓存的相关信息(稍微过时的签名)-在JNI中,如何根据IBM的性能建议缓存类、方法ID和字段ID?

标题:

extern jclass java_class_boolean;
extern jmethodID java_method_boolean;

CPP:

jclass java_class_boolean;
jmethodID java_method_boolean;
....
void initStatic(JNIEnv* env){
    java_class_boolean = env->FindClass("java/lang/Boolean");
    if (java_class_boolean){
        env->NewGlobalRef(java_class_boolean);
        java_method_boolean = env->GetMethodID(java_class_boolean, "<init>", "(Z)V");
    }
}

用法(不同的CPP类,导入共享头):

    jclass bc = env->FindClass("java/lang/Boolean");
    jmethodID bm = env->GetMethodID(bc, "<init>", "(Z)V");

    std::cout << "\nClass new: ";
    std::cout << bc;
    std::cout << " Class old: ";
    std::cout << java_class_boolean;
    std::cout << "\nMethod new: ";
    std::cout << bm;
    std::cout << " Method old: ";
    std::cout << java_method_boolean;
    std::cout << "\n";
    result2 = env->NewObject(bc, bm, 1);

后果

新类:0x7fcce4430110旧类:0x7fcce6a23098新方法:0x7fcce471c288旧方法:0x7fcce471c288

但是如果使用缓存的类运行,它会给出一个分段错误。

操作系统是Mac 10.12。JDK 1.8.0_25。

此外,到目前为止的测试都是单线程的,JNI环境也是一样的。

环境打印说明:(JNIEnv*)环境=0x00007fcc3e0011e8环境打印说明:(JNIEnv*)环境=0x00007fcc3e0011e8

initStatic和未来的用法都在“线程4”上,使用相同的env实例(由JNI传递,而不是缓存)。还有其他线程,但segfault和init在同一个线程上。

共有1个答案

云锦
2023-03-14

问题是我没有意识到这一点-

我创建这个函数是为了解决这个问题。

inline jclass find_class_global(JNIEnv* env, const char *name){
    jclass c = env->FindClass(name);
    jclass c_global = 0;
    if (c){
        c_global = (jclass)env->NewGlobalRef(c);
        env->DeleteLocalRef(c);
    }
    return c_global;
}
 类似资料:
  • 问题内容: 加载子类的正确FindClass标识符语法是什么?例如: 为了得到我所能做的,但试图获得通过抛出一个。代表子类有不同的语法吗? 问题答案: 没关系,该工具在这里证明是有用的。正确的语法是:

  • JNI++项目提供了两个代码生成实用程序和一个旨在简化用 C++ 进行JNDI 编程的核心C++ 库。使用仅具有相对简单的数据结构的本机C/C++ 类来编写简单的JNI 程序,即这些程序仅访问字段和使用简单的访问方法(accessor)和修改方法(modifier method),这是相当容易的。JNI++ 生成许多从Java 语言访问C++ 类(或C++到Java)所必需的大量代码。

  • 问题内容: 我目前在一个项目中同时使用C 和Java,并且希望能够将包含在C 中的对象发送到我的Java接口,以便通过GUI对其进行修改,然后将所做的修改发送回C ++中。 到目前为止,我一直没有通过JNI接口向Java返回int或boolean值。这次我必须通过接口发送对象。我已经在C ++和Java中提供了类似的类定义。 我想知道如何创建对象,以便可以在Java中使用它。 在C ++中,我有:

  • LevelDB JNI 提供了 Google 高效的Key/Value数据库 LevelDB 的 Java 接口。 示例代码: import org.fusesource.leveldbjni.*;import static org.fusesource.leveldbjni.DB.*;import java.io.*;Options options = new Options();options

  • 在下面的代码中,我需要在for循环中调用ReleaseStringUTFChars还是只调用一次(使用任何一个const char*)? 提前谢了。

  • 文档和快速引用可以在sample_for_tests.h和SampleForTests.java找到。 Overview On other platforms, the underlying system / platform APIs (win32, cocoa, gtk) are directly accessible via C/C++. On Android, the underlying