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

How do I call a Java method from C (without first calling C from Java)

本文关键字:调用 Java 方法      更新时间:2023-10-16

因此,如果您想从Java调用C,我理解生成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",它不会打印任何内容。

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而不是GetMethodID,并使用CallStaticVoidMethod而不是CallVoidMethod。然后可以完全省略第一个jobject参数。

env->CallStaticVoidMethod(doSomethingMethod, buf);