1

我正在尝试通过 JNI (Clang C-API) 使用 Clang。几次迭代后,它会停止创建新对象并崩溃:

映射方法 0 args:创建方法实例 0x7fa26ba23c90 0x7fa26ba2a0c0 libclang:在索引源文件期间检测到崩溃:{'source_filename':'/Users/asmirnov/Documents/dev/src/clang_jni/mac/test/TestFile.h''command_line_args
': ['-c', '-x', 'c++'], 'unsaved_files' : [],
'options' : 0, }

代码非常简单:

mapMethod(JNIEnv *env, const CXIdxDeclInfo *info) {

    debug("map method");

    int numArgs = clang_Cursor_getNumArguments(info->cursor);
    debug("  %i args:", numArgs);

    debug("create Method instance %p %p", MethodClass, MethodConstructor);
    jobject result = env->NewObject(MethodClass, MethodConstructor);

    debug("create Method  params instance");

方法类和构造函数被正确地找到并注册为全局变量(似乎是),并且它的工作迭代很少:

// method
    MethodClass = (jclass)env->NewGlobalRef(env->FindClass("name/antonsmirnov/clang/dto/index/Method"));
    debug(MethodClass != NULL ? "found MethodClass" : "not found MethodClass");

    MethodConstructor = env->GetMethodID(MethodClass, "<init>", "()V");
    debug(MethodConstructor != NULL ? "found MethodConstructor" : "not found MethodConstructor");

我已经阅读了一些“jni 提示和技巧”文章,并试图env->DeleteLocalRef让本地引用计数太大而无法尝试,但没有结果:

// magic 
    jint ensureResult = env->EnsureLocalCapacity(1024);
    debug("ensure result %i", ensureResult);

    jint pushResult = env->PushLocalFrame(1024);
    debug("push result %i", pushResult);

Clang 正在劫持异常,所以我看不出真正的原因。正如我所说,问题发生在几次迭代之后,所以它似乎是一些超出限制的问题或smth。

怎么了?

更新:我做了一些研究,我发现如果我在此之前删除一些本地变量,我可以获得更多的迭代和更多的对象实例。所以它让我觉得它确实使用了 16 个本地变量,而忽略了我的EnsureLocalCapacity调用。应该在哪里做?

4

2 回答 2

1

修复了使用EnsureLocalCapacityin JNI_OnLoad()(在每个本机方法调用中都不起作用)。

于 2013-11-11T08:17:07.847 回答
1

通过 NewObject、FindClass 创建的对象,需要通过 DeleteLocalRef() 释放,因为 jni 中局部变量的数量是有限的。或者你可以使用EnsureLocalCapacityin JNI_OnLoad()

于 2020-11-27T09:33:00.600 回答