调用java方法

时间:2011-06-15 23:42:43

标签: c++ java-native-interface android-ndk

我今天用Android SDK用Java创建了我的第一个原生调用 我找到了一些例子但是与函数头没有一致。

我总是使用

JNIEXPORT void JNICALL Java_com_test_Calculator_calcFileSha1 
   (JNIEnv *, jclass, jstring);

但我见过

JNIEXPORT void JNICALL Java_com_test_Calculator_calcFileSha1 
   (JNIEnv *, jobject, jstring);

归属于不同的是获得来电者的班级 但是首选方式是什么?

从C ++代码我想调用一个java方法。我找到了JNI文档(Calling Instance Methods) 但我不知道第一个参数(对象)应该是什么。

我试图给出我从本机方法调用得到的类实例,该实例方法因AbstractMethodError而失败。

修复源代码:

public class TestCalc extends Activity {
   static {
      System.loadLibrary("Test");
   }

   private void setFilesize(long size) {

   }
}

原生图书馆:

// header
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_com_test_TestCalc_calcFilesize
  (JNIEnv *, jobject, jstring);

  void setFilesize(const INT_64 size);

#ifdef __cplusplus
}
#endif

#endif

// code
JNIEnv * callEnv;
jobject callObj;


JNIEXPORT void JNICALL Java_com_test_SHA1Calc_calcFileSha1
  (JNIEnv * env, jobject jobj, jstring file)
{
    callEnv = env;
    callObj = jobj;

    [...]
}

  void setFilesize(const INT_64 size) {
      jmethodID mid;
      jclass cls;

      cls=callEnv->FindClass("com/test/TestCalc");    
      mid=callEnv->GetMethodID(cls, "setFilesize", "(J)V");
      if (mid == 0) {
        __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:LC: [%s]", "Cannot find method setFilesize");
        return;
      }

      callEnv->ExceptionClear();
      callEnv->CallVoidMethod(callObj, mid, size);
      if(callEnv->ExceptionOccurred()) {
        callEnv->ExceptionDescribe();
        callEnv->ExceptionClear();
      }
  }

感谢您的任何建议。

2 个答案:

答案 0 :(得分:2)

调用[type]方法仅适用于私有方法和构造函数。 (Calling Instance Methods)当您调用公共方法时,您将获得AbstractMethodError

答案 1 :(得分:0)

jobject可以是任何java对象,而jclass应该是表示java.lang.Class的对象。在C API中,jobjectjclass是相同的,而C ++ API正在尝试强制执行类型安全,并将其声明为jclass继承jobject的不同类型。第二个参数应该代表一个类,因此jclass是首选。即使在C中没关系,它也可以暗示开发人员甚至可以节省您的时间,如果您决定切换到C ++。阅读有关JNI类型here的更多信息。