开发者

Call a java method

开发者 https://www.devze.com 2023-03-13 03:08 出处:网络
开发者_Python百科I have created my first native call in Java with the Android SDK today. I found a few examples but there aren\'t consistent with the function head.
开发者_Python百科

I have created my first native call in Java with the Android SDK today.

I found a few examples but there aren't consistent with the function head.

I used always

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

but I have seen

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

Belonging to the heads are different was to get the class of the caller.

But what is the preferred way?

From the C++ code I want to call a java method. I found the JNI documentation (Calling Instance Methods).

But I don't know what the first parameter (object) should be.

I tried to give the class instance which I get from the call of the native method, which fails with an AbstractMethodError.

Fixed source code:

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

   private void setFilesize(long size) {

   }
}

Native Library:

// 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();
      }
  }

Thanks for any advices.


Call[type]Method is only for private methods and constructors. (Calling Instance Methods) When you call a public method, you will get an AbstractMethodError.


jobject could be any java object while jclass is supposed to be an object representing java.lang.Class. In C API, jobject and jclass is the same thing while C++ API is trying to enforce type safety and declares those as different types where jclass inherits jobject. The second argument is supposed to represent a class, so jclass is preferred. Even if in C it doesn't matter, it can hint the developer or even save you time if you ever decide to switch to C++. Read more about JNI types here.

0

精彩评论

暂无评论...
验证码 换一张
取 消