如何从C调用Java方法(不首先从Java调用C)

时间:2013-02-22 16:29:05

标签: c++ java-native-interface

所以我理解生成C头的常用过程,如果你想从Java调用C,但我不明白我应该使用什么函数调用,如果我没有“jobject”给出。 就像在这里一样,我试着打电话给doSomething()

public class Test {

   public void doSomething(ByteBuffer buf) { 
         System.out.println("Hi"); 
   };
}

我读过这篇文章,但我不明白: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp16656

jobject buf = env->NewDirectByteBuffer(b, len);

jclass testClass;
jmethodID doSomethingMethod;

testClass = env->FindClass("test/Test");
doSomethingMethod = env->GetMethodID(testClass, "doSomething", "(Ljava/nio/ByteBuffer;)V");
env->CallVoidMethod(buf, doSomethingMethod);

“CallVoidMethod()”的第一个参数应该是什么?这总是工作,但是什么? 当我运行它时,它只是在Eclipse中告诉我“UnsupportedOperationException”,它不会打印任何内容。

1 个答案:

答案 0 :(得分:1)

CallVoidMethod的第一个参数应该是jobject,指的是有问题的类的实例。你实际上是在传递一个字节缓冲区,这是一个完全不同的东西。

您查找类和类中的方法,但您不是在任何地方创建(或获取)该类的实际对象。这是你失去的一步。

在对象和方法参数之后,应该传递 Java方法的字节缓冲区参数。类似的东西:

env->CallVoidMethod(testObj, doSomethingMethod, buf);

您需要找到一种方法将testObj设置为有意义的内容。


如果您实际上不想实例化对象,则必须更改Java代码以将doSomething()转换为static方法。

public class Test {
   public static void doSomething(ByteBuffer buf) { 
         System.out.println("Hi"); 
   };
}

然后更新您的C ++代码,使用GetStaticMethodID代替GetMethodIDCallStaticVoidMethod代替CallVoidMethod。然后,您可以完全省略第一个jobject参数。

env->CallStaticVoidMethod(doSomethingMethod, buf);