【发布时间】:2019-04-15 03:37:40
【问题描述】:
当通过 JNI 在 C 和 Java 之间来回调用时,我遇到了一个奇怪的堆栈问题。
我们的代码是 C 和 Java 模块的混合体,它们可以使用 JNI 相互调用。
当以下情况发生时,我的问题似乎发生了;
C 模块 (CA.c) 调用 Java 模块 (JA.java),后者调用 C 模块 (CB.c),后者尝试调用 Java 模块 (JB.java),但失败。
CB 确实进行了一些成功运行的 Java 调用,但是一旦堆栈上有一定数量的函数,JNI 似乎开始失败:
CB.c
func1() {
CallJavaViaJNI(); //Works fine
func2();
CallJavaViaJNI(); //Works fine
}
func2() {
CallJavaViaJNI(); //Works fine
func3();
CallJavaViaJNI(); //Works fine
}
func3() {
CallJavaViaJNI(); //Fails
}
在上面的例子中,从 func1() 和 func2() 调用 CallJavaViaJNI() 时会成功,但在 func3() 中调用会失败(jnienv->ExceptionCheck() 返回 true)。此外,在 func3() 之后发生的 func1() 和 func2() 中对 CallJavaViaJNI() 的调用起作用。
这只是一个例子,堆栈上的函数可能比这多得多。一旦堆栈上有这么多,JNI 似乎就会停止工作。函数从堆栈中弹出后,事情又开始工作了。
我尝试在 ExceptionCheck() 返回 true 后调用 ExceptionDescribe(),但我什么也没得到。清除异常并重试结果相同。
这与JNI的初始化有关吗?我需要指定堆栈大小或其他参数吗?
当从一个从 C 调用的 Java 模块回调到 C 时,有什么特别需要做的吗?文档对此不是很清楚。
如果有任何帮助或指点,我将不胜感激。
【问题讨论】:
-
CallJavaViaJNI到底是做什么的?在所有这些情况下都是一样的吗?你说你从ExceptionDescribe中一无所获。这是否意味着您没有发现输出有用,或者您根本没有得到任何输出?在后一种情况下,您确定您没有将 STDERR 重定向到/dev/null或类似的东西吗? -
CallJavaViaJNI() 将使用类似 CallStaticVoidMethod() 的方式调用 Java 模块。在此调用之后,ExceptionCheck() 返回 true。至于 ExceptionDescribe(),它似乎返回一个空字符串。
-
你尝试过扩展线程栈大小吗?
-
我使用了
ulimit -s unlimited,但没有效果。
标签: java c java-native-interface