使用NDK从Native代码调用Java函数

时间:2012-07-24 16:50:52

标签: android c android-ndk

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

我正在创建一个Android应用程序,它使用NDK在C中使用现有库。我遇到的问题是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方法吗?

1 个答案:

答案 0 :(得分: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。