Calling a Java Method from Native Code
http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/method.html
Calling Java Methods
This section illustrates how you can call Java methods from native methods. Our example program,
Callbacks.java, invokes a native method. The native method then makes a call back to a Java method. To make things a little more interesting, the Java method again (recursively) calls the native method. This process continues until the recursion is five levels deep, at which time the Java method returns without making any more calls to the native method. To help you see this, the Java method and the native method print a sequence of tracing information.Calling a Java Method from Native Code
Let us focus on the implementation of
Callbacks_nativeMethod, implemented inCallbacks.c. This native method contains a call back to the Java methodCallbacks.callback.JNIEXPORT void JNICALL
Java_Callbacks_nativeMethod(JNIEnv *env, jobject obj, jint depth)
{
jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "(I)V");
if (mid == 0)
return;
printf("In C, depth = %d, about to enter Java\n", depth);
(*env)->CallVoidMethod(env, obj, mid, depth);
printf("In C, depth = %d, back from Java\n", depth);
}You can call an instance (non-static) method by following these three steps:
- Your native method calls
GetObjectClass. This returns the Java class object to which the Java object belongs.- Your native method then calls
GetMethodID. This performs a lookup for the Java method in a given class. The lookup is based on the name of the method as well as the method signature. If the method does not exist,GetMethodIDreturns 0. An immediate return from the native method at that point causes aNoSuchMethodErrorto be thrown in Java code.- Lastly, your native method calls
CallVoidMethod. This invokes an instance method that hasvoidreturn type. You pass the object, method ID, and the actual arguments toCallVoidMethod.Forming the Method Name and Method Signature
The JNI performs a symbolic lookup based on the method's name and type signature. This ensures that the same native method will work even after new methods have been added to the corresponding Java class.
The method name is the Java method name in UTF-8 form. Specify the method name for a constructor of a class by enclosing the word
initwithin angle brackets (this appears as "<init>").Note that the JNI uses method signatures to denote the type of Java methods. The signature
(I)V, for example, denotes a Java method that takes one argument of typeintand has return typevoid. The general form of a method signature argument is:"(argument-types)return-type"The following table summarizes the encoding for the Java type signatures:
Java VM Type Signatures
Signature Java Type Z boolean B byte C char S short I int J long F float D double L fully-qualified-class ; fully-qualified-class [ type type[] ( arg-types ) ret-type method type For example, the
Prompt.getLinemethod has the signature:(Ljava/lang/String;)Ljava/lang/String;whereas the
Callbacks.mainmethod has the signature:([Ljava/lang/String;)VArray types are indicated by a leading square bracket ([) followed by the type of the array elements.
Using
javapto Generate Method SignaturesTo eliminate the mistakes in deriving method signatures by hand, you can use the
javaptool to print out method signatures. For example, by running:javap -s -p Promptyou can obtain the following output:
Compiled from Prompt.java
class Prompt extends java.lang.Object
/* ACC_SUPER bit set */
{
private native getLine (Ljava/lang/String;)Ljava/lang/String;
public static main ([Ljava/lang/String;)V
<init> ()V
static <clinit> ()V
}The "-s" flag informs
javapto output signatures rather than normal Java types. The "-p" flag causes private members to be included.Calling Java Methods Using Method IDs
In JNI, you pass the method ID to the actual method invocation function. This makes it possible to first obtain the method ID, which is a relatively expensive operation, and then use the method ID many times at later points to invoke the same method.
It is important to keep in mind that a method ID is valid only as long as the class from which it is derived is not unloaded. Once the class is unloaded, the method ID becomes invalid. So if you want to cache the method ID, make sure to keep a live reference to the Java class from which the method ID is derived. As long as the reference to the Java class (the
jclassvalue) exists, the native code keeps a live reference to the class. The section Local and Global References explains how to keep a live reference even after the native method returns and thejclassvalue goes out of scope.Passing Arguments to Java Methods
The JNI provides several ways to pass arguments to a Java method. Most often, you pass the arguments following the method ID. There are also two variations of method invocation functions that take arguments in an alternative format. For example, the
CallVoidMethodVfunction receives the arguments in ava_list, and theCallVoidMethodAfunction expects the arguments in an array ofjvalueunion types:typedef union jvalue {
jboolean z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject l;
} jvalue;Besides
CallVoidMethodfunction, the JNI also supports instance method invocation functions with other return types, such asCallBooleanMethod,CallIntMethod, and so on. The return type of the method invocation function must match with the Java method you wish to invoke.Calling Static Methods
You can call static Java method from your native code by following these steps:
- Obtain the method ID using
GetStaticMethodID, as opposed toGetMethodID.- Pass the class, method ID, and arguments to the family of static method invocation functions:
CallStaticVoidMethod,CallStaticBooleanMethod, and so on.If you compare instance method invocation functions to static method invocation functions, you will notice that instance method invocation functions receive the object, rather than the class, as the second argument following the JNIEnv argument. For example, if we add a static method
static int incDepth(int depth) {return depth + 1};into
Callback.java, we can call it fromJava_Callback_nativeMethodusing:JNIEXPORT void JNICALL
Java_Callbacks_nativeMethod(JNIEnv *env, jobject obj, jint depth)
{
jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID mid = (*env)->GetStaticMethodID(env, cls, "incDepth", "(I)I");
if (mid == 0)
return;
depth = (*env)->CallStaticIntMethod(env, cls, mid, depth);Calling Instance Methods of a Superclass
You can call instance methods defined in a superclass that have been overridden in the class to which the object belongs. The JNI provides a set of
CallNonvirtual<type>Methodfunctions for this purpose. To call instance methods from the superclass that defined them, you do the following:
- Obtain the method ID from the superclass using
GetMethodID, as opposed toGetStaticMethodID).- Pass the object, superclass, method Id, and arguments to the family of nonvirtual invocation functions:
CallNonvirtualVoidMethod,CallNonvirtualBooleanMethod, and so on.It is rare that you will need to invoke the instance methods of a superclass. This facility is similar to calling a superclass method, say
f, using:super.f();in Java.
Calling a Java Method from Native Code的更多相关文章
- NDK(3)java.lang.UnsatisfiedLinkError: Native method not found解决方法
调用native方法时报错如下 : “java.lang.UnsatisfiedLinkError: Native method not found.... ”: 原因分析: 链接器只看到了在so中 ...
- java.lang.UnsatisfiedLinkError: Native method not found 三种可能解决方案
so文件编译生成后,运行时,有时候会遇到java.lang.UnsatisfiedLinkError: Native method not found问题,有可能是以下三种因素: 一.Jni方法头部大 ...
- 修改Android 4.2.2的原生Camera引出的java.lang.UnsatisfiedLinkError: Native method not found,及解决方法
修改Android 4.2.2的原生Camera应用,做一些定制,将Camera的包名从之前的 package com.android.* 修改成了com.zhao3546.*. 调整后,应用可以正常 ...
- [Xamarin] 透過Native Code呼叫 JavaScript function (转帖)
今天我們來聊聊關於如何使用WebView 中的Javascript 來呼叫 Native Code 的部分 首先,你得先來看看這篇[Xamarin] 使用Webview 來做APP因為這篇文章至少講解 ...
- NDK开发历程(一):android native code的调试方法
引用:http://www.cnblogs.com/ychellboy/archive/2013/02/22/2922683.html 使用NDK在android上做开发是一件“痛并快乐着”的差事,之 ...
- java基础-关键字-native
一. 什么是Native Method 简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个java的方法:该方法的实现由 ...
- java中的native方法和修饰符(转)
Java中的native修饰符 今天偶然看代码,发现别人有这样写的方法,并且jar里面有几个dll文件,比较奇怪,于是把代码打开,发现如下写法. public native String GSMMod ...
- Java中的native方法
博客引用地址:Java中的native方法 今天花了两个小时把一份关于什么是Native Method的英文文章好好了读了一遍,以下是我依据原文的理解. 一. 什么是Native Method 简单地 ...
- Java中的native关键字与JNI
一.先说一下大致的意思: jdk提供的类库源代码中有一些方法没有实现,这些方法前有native关键字,如object类中的 : native Object clone() throws CloneNo ...
随机推荐
- Error while adding new interface: failed to open /dev/vboxnetctl: No such file or directory
Try this : sudo modprobe vboxnetadp ref: https://github.com/gasolin/foxbox/issues/32
- C# 大图片压缩算法,减少图片体积
声明: 图片压缩算法,不建议对小图片进行压缩,一般文件小于1m的,真心没必要压缩, 图片很小的,例如:几百KB的图片,有可能不会减少图片体积,反而压缩后更大,也很正常, 请大家合理使用,并不是,所有图 ...
- OpenGL 遮挡查询
原文地址:http://www.linuxidc.com/Linux/2015-02/114036.htm 在一个场景中,如果有有些物体被其他物体遮住了不可见.那么我们就不需要绘制它.在复杂的场景中, ...
- CentOS 7 64位更换内核安装锐速破解版
1.更新内核 rpm -ivh http://soft.91yun.org/ISO/Linux/CentOS/kernel/kernel-3.10.0-229.1.2.el7.x86_64.rpm - ...
- Python 多线程相关知识学习
多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进 ...
- Git项目协同开发学习笔记1:项目库开发基础git命令
这年头git基本都是项目开发的标配,之前刚好碰到了就花了两天时间系统学习了下.本文内容基本来自以下tutorial:Learn Git(建议直接去看原文,因为这个网站是有更新的).这个是我看过对git ...
- Phpcms V9单页添加自定义字段
说起文章自定义自段,大家都会想到 wordpress 的自定义字段,确实 wordpress 系统很强大,字段可以很灵活的在后台进行添加与更新,并能够很好的在前台进行调用,对于这点 phpcms v9 ...
- pyqt与拉勾网爬虫的结合
人力部需要做互联网金融行业的从业人员薪酬分析,起初说的是写脚本,然后他们自己改.但这样不太好,让人事部来修改py脚本不太好,这需要安装py环境和一些第三方包,万一脚本改来改去弄错了,就运行不起来了. ...
- MsChart,饼状图
HTML 后台代码:(dt为数据源)数据库中数据Sample 1 Chart1.Series["Series1"].Label = "#PERCENT{P}"; ...
- 让你的应用支持新iPad的Retina显示屏
一.应用图片标准iOS控件里的图片资源,苹果已经做了相应的升级,我们需要操心的是应用自己的图片资源.就像当初为了支持iPhone 4而制作的@2x高分辨率版本(译者:以下简称高分)图片一样,我们要为i ...