我有一个通过JNI调用接口调用Java模块的C例程。我在使用C模块和JNI时对Java方法的调用返回NULL字符串的问题,但是当我在命令行使用Java时,Java模块返回错误和默认值值。
这是我绕过C代码并在命令行中通过Java调用Method
时返回的数据$ java ClassName" This" "是" "我" "测试" "串"
SomethingElse.Method上的异常:[Function:DifferentMethod] ExceptionClassException:ExceptionClassExceptionException:[Function:CFBDynamicMessage :: getCodePage] codePageBytes为NULL,UTF-8返回字符串 - 我试图获得数据 0.0 | | 0.0 | | 0.0 || | 0.0 | 0 | | 0.0 | | || 0.0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 ||
我需要获取返回的字符串,即使在java端出现错误也是如此。为了试着看看C和JNI中发生了什么,我调高了JNI的调试级别:
options[1].optionString = "-Xdebug"; /* print JNI-related messages */
options[2].optionString = "-Xlog:all";
// this next line allows us to continue processing after the Java
// error. Unfortunately the code then SegFaults further on.
options[3].optionString = "-Xcheck:jni:nonfatal";
options[4].optionString = "-verbose:jni";
JNI启动JVM,找到类和方法并构建我需要传递给方法的Java字符串,但是当我尝试执行该方法时,我收到以下错误:
JVMJNCK048E CallObjectMethod / CallObjectMethodV中的JNI错误:不合格的接收者 JVMJNCK080E在连接线程的最外层帧中检测到错误 JVMJNCK023E检测到JNI错误。继续... 分段错误(核心转储)
这是C代码(为简洁起见,我正在删除一些错误检查和空格):
res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
cls = (*env)->FindClass(env, "GenericClassName");
mid = (*env)->GetMethodID(env, cls, "execute", "(Ljava/lang/Object;)Ljava/lang/Object;");
jstr = (*env)->NewStringUTF( env, "This|is|my|test|string|");
// This next line is the one that throws the ineligible receiver error
jstring resultStr = (*env)->CallObjectMethod(env, cls, mid, jstr);
// ExceptionOccurred(env) is false; no errors are displayed
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
}
const char *nativeString = (*env)->GetStringUTFChars(env, resultStr, JNI_FALSE);
// This next line calls the SegFault
fprintf(stdout, "%s\n", *nativeString);
我已经使用gdb来查看SegFault创建的核心转储,以下是我认为的相关结果:
print nativeString
$ 1 = 0x8dfaa80" [Ljava.lang.Class; @ 34ca34ca"
print * nativeString
$ 2 = 91' ['
这是我调用的java方法的定义:
public Object execute (Object args) throws Exception { ... }
我们将非常感谢您对此问题提供的任何帮助或见解。当我尝试使用谷歌获取不合格的接收器错误时,我得到了一堆关于足球的链接,但在JNI或Java中没有任何内容。我花了最近几天在Stack Overflow网站上搜索,尽管有一些很有希望的问题,但它们都与Android有关,并没有为解决我的问题提供任何额外帮助。
作为最后两个笔记,即使您无法提供帮助,也要感谢您阅读此内容,我的环境是64位RHEL服务器,但C代码和JVM都作为32位应用程序运行。
TL; DR-C通过JNI调用Java方法,我得到一个错误代码(CallObjectMethod / CallObjectMethodV中的JNI错误:不合格的接收者),这导致Google告诉我所有关于我能做的所有运动的信息。因为我正在研究这个问题。
答案 0 :(得分:1)
你提供的是一个类而不是一个对象。所以你试图调用Class<GenericClassName>.execute(Object arg).
你需要一个类的实例。