NDK[2]Java方法到C方法 和 C方法到Java方法

【参考链接】

 

程序运行时,以主线程的main()方法为入口,不停的从一个方法调用到另一个方法中,方法返回再继续调用其他的

根据之前JVM的知识,其实就是在不停向栈中压入栈帧、弹出栈帧

所以既可以在java方法中调用C/C++方法,也可以在C/C++方法中调用Java方法,只不过这两种栈是分开维护的。

 

Java方法到C/C++方法

给一个类定义一个native方法,实现其对应的C/C++方法,在Java中调用这个native方法就会去调用C/C++方法

这个native方法可以是非static的,其对应方法的前两个参数的类型为JNIEnv,jobject,

也可以是static的,其对应方法的前两个参数的类型为JNIEnv,jclass

这些类型都是在jni.h中定义的,其中

JNIEnv,其在C中的定义为结构体JNINativeInterface的指针,后续主要就是使用这个类型中的各种函数指针(指向函数的指针

jobject,代表调用的这个Java对象,jclass,代表调用的这个Java类,如果在C/C++中要使用的正是这个对象/这个类,则不用去重新获取。

 

 

C/C++方法到Java方法

在C/++方法中调用Java方法,代码跟反射有点像,需要先获取到这个方法,然后再调用这个方法。

获取方法主要通过JNIEnv的如下方法

需要知道这个方法的描述符,这在Class文件结构中已讲过,此外还可以通过先编译然后执行javap –s指令得到

调用方法主要通过JNIEnv的如下方法

 

 

 

以如下代码为例

先从Java方法中调用到C方法nativeMethod1,然后再去调用Java类Test1的某个新建对象的非静态方法test();

先从Java方法中调用到C方法nativeMethod2,然后再去调用Java类Test2的静态方法test();

public class MainActivity extends Activity {

   
public nativevoid nativeMethod1();

   
public static native void nativeMothod2();

   
@Override
   
protected void onCreate(BundlesavedInstanceState) {
       
super.onCreate(savedInstanceState);
       
setContentView(R.layout.activity_main);

       
System.loadLibrary("testtt");
   
}

   
public void onClick1(View view){
       
nativeMethod1();
   
}

   
public void onClick2(View view){
       
nativeMothod2();
   
}
}

 


#include "com_example_shadowfaxghh_demo_MainActivity.h"

JNIEXPORT void JNICALL Java_com_example_shadowfaxghh_demo_MainActivity_nativeMethod1
       
(JNIEnv *env, jobject jobj) {

   
//调用Test1的成员方法test()
   
//获取到类
   
jclass clazz=(*env)->FindClass(env, "com/example/shadowfaxghh/demo/Test1");
   
//获取到方法//GetMethodID
   
jmethodID methodID=(*env)->GetMethodID(env, clazz, "test", "()V");

   
//创建对象
   
jobject jobj2=(*env)->AllocObject(env, clazz);
   
//调用方法//CallVoidMethod
   
(*env)->CallVoidMethod(env, jobj2, methodID);
}

JNIEXPORT void JNICALL Java_com_example_shadowfaxghh_demo_MainActivity_nativeMothod2
       
(JNIEnv *env, jclass jclazz) {
   
//调用Test2的成员方法test()//静态
   
//获取到类
   
jclass clazz=(*env)->FindClass(env, "com/example/shadowfaxghh/demo/Test2");
   
//获取到方法//GetStaticMethodID
   
jmethodID methodID=(*env)->GetStaticMethodID(env, clazz, "test", "()V");

   
//调用方法//CallStaticVoidMethod
   
(*env)->CallStaticVoidMethod(env, clazz, methodID);
}

 

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值