Android NDK使用不同的命名空间调用本机方法

时间:2014-06-13 11:42:26

标签: java android android-ndk

我是JNI编程的新手 我可以从不同的JNI名称空间定义中调用本机方法吗?

例如:

package com.example.hellojni;
public class HelloJni extends Activity
{
  public native int MyMethod();  
  public native int OtherMethod();   // this works have the namespace package=jniexport interface

  static {System.loadLibrary("hello-jni");}

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    int b = OtherMethod(); //works
    int a = MyMethod(); //ERROR java.lang.reflect.InvocationTargetException 
 }
}

   ================File.c================
    JNIEXPORT int JNICALL Java_Cardioline_HelloJni_MyMethod(JNIEnv *env, jobject thisObj) 
  {
return 1;
  }
   JNIEXPORT int JNICALL Java_com_example_hellojni_HelloJni_OtherMethod(JNIEnv *env, jobject thisObj)
 {
 return 2;
  }

2 个答案:

答案 0 :(得分:2)

不,JNI方法名称由javah预先确定。从这里开始尝试:

http://blog.edwards-research.com/2012/04/tutorial-android-jni/

javah将为您提供标头,您必须将方法声明复制到.c文件中。

如果您要在另一个类中调用JNI方法,请在java中调用另一个类。基本上改变这个:

int a = MyMethod();

到此:

int a = new CardioLine.HelloJni().MyMethod();

通常,我将Java文件一对一映射到.c / .cpp文件。这可能也是你想要的(对于使用本机方法的Java类)。

答案 1 :(得分:1)

正如@JonnyBoy在他的回答中解释的那样,JNI本机函数的名称与使用此函数作为本机方法的Java类的完整名称紧密耦合。 HelloJni包中com.example.hellojni类的全名是com.example.hellojni.HelloJni,因此它查找名称以Java_com_example_hellojni_HelloJni_开头的本机函数。

幸运的是,Android中并不要求所有课程都在应用包下。例如,您注册为com.example.hellojni的应用可以免费包含并使用包CardioLine和类CardioLine.HelloJni

简单Android项目的目录结构将包含如下树:

src
  com
    example
      hellojni
         HelloJni.java
  CardioLine
     HelloJni.java

另一方面,如果您在本机库中包含 JNI_OnLoad() 功能,并使用 RegisterNatives() ,那么您的Java类可以具有原生功能方法,无论其出口名称如何。