3

前几天我问了这个问题,但不是太具体,所以我想重新澄清一下。

我正在使用 NDK 创建一个使用 C 中现有库的 Android 应用程序。我遇到的问题是C代码使用了很多java没有的东西(函数指针作为参数是个大问题)。

无论如何,我想知道是否可以在我的 Java 代码中编写 C 代码调用的函数。现在,据我所知,您可以做到,所以如果没有人回答“是的,您可以,LINK,我将不胜感激。” .

任何人都可以尝试解释这个过程吗?我知道这涉及在 C 代码中创建 JVM;任何有助于新手站起来的信息都将不胜感激。

谢谢

编辑 :

所以,我不知道这三个步骤该怎么做。

To call a specific Java function from C, you need to do the following:

Obtain the class reference using the FindClass(,,) method.
Obtain the method IDs of the functions of the class that you want to call using the 
GetStaticMethodID and GetMethodID function calls.

Call the functions using CallStaticVoidMethod, CallStaticIntMethod, and CallStaticObjectMethod.

这没有太多解释,我在 C 方面几乎没有经验。 FindClass 是 C 方法吗?

4

1 回答 1

4

每个可通过 JNI 从 Java 调用的 C 函数都有一个类型为 的第一个参数JNIEnv*。在 C 端,这是一个指向一个结构的指针,该结构带有一堆指向函数的指针。这些函数是您与 Java 世界的接口。FindClassGetMethodID其余的都在其中。

因此,当您想从 C 端调用 FindClass 时,您可以这样做:

void Java_com_mypackage_MyClass_MyMethod(JNIEnv *jniEnv, jobject thiz)
{
    jclass *clazz = (*(*jniEnv)->FindClass)(jniEnv, "com/mypackage/SomeClass");
    jmethodID MethodID = (*(*jniEnv)->GetStaticMethodID)(jniEnv, clazz, "SomeMethod", "(I)I");
    int result = (*(*jniEnv)->CallStaticIntMethod)(jniEnv, clazz, MethodID, 18);

等等。该行取消引用jniEnv参数,获取函数指针并通过它调用函数。自然,类和方法名完全是伪造的。我怎么会知道你的。

注意:我在这里谈论的是函数指针,但与您的意义不同;这些是指向 JNI 提供的函数的函数指针,而不是指向您的函数的函数指针。

调用语法的冗长与 C 的局限性有关。在 C++ 中,您可以改为编写

jclass *cl = jniEnv->FindClass("com/mypackage/SomeClass");

因为 C++ 通过虚函数本机支持这种类型的函数表指针。

在此过程中,您可能会走一些捷径。如果您在与 C 入口点相同的类中调用方法,并且它恰好是静态的,那么您的第二个参数已经是类对象指针。如果您有一个this指向要调用方法的对象的指针,则可以使用 GetObjectClass。

于 2012-07-25T01:16:07.213 回答