(JNI)c代码利用反射调用java方法

来源:互联网 发布:怎么执行php图片木马 编辑:程序博客网 时间:2024/05/25 08:11

反射一般分3个步骤:
1.加载calss(字节码),获取class的对象。
2.获取对应的方法或属性。
3.修改属性,或执行方法。


首先回顾一下java中的反射
 写一个类JK:
public class Jk {     public void p(String s) {          System. out.println(s);     }}

另一个Test类来反射此类,执行p(String)方法:
public class Test {     public static void main(String[] args) {           try {              Class clazz = Test.class.getClassLoader().loadClass("Jk" );              Method method = clazz.getDeclaredMethod("p" ,                         new Class[] { String.class });              method.invoke(clazz.newInstance(), new String[] { "java反射" });          } catch (Exception e) {              e.printStackTrace();          }     }}


控制台输出:  
     java反射

c代码利用反射调用java方法:
目标:在MainActivity中放一个按钮,点击按钮,按钮执行native 方法jk();c语言jk()函数反射执行MainActivity中的jkShow()方法,jkShow()方法弹出Toast。
     1.MainActivity.java类
public class MainActivity extends Activity {     static{          System. loadLibrary("jk");     }     @Override     protected void onCreate(Bundle savedInstanceState) {           super.onCreate(savedInstanceState);          setContentView(R.layout. activity_main);     }     public void onclick(View view) {          jk();     }     public native void jk();     public void jkShow(String message) {          Toast. makeText(this, message, 0).show();     }}


  2.jk.c
#include <jni.h>//c代码利用反射调用java方法JNIEXPORT void JNICALL Java_com_jk184_cj_MainActivity_jk(JNIEnv * env,           jobject jobj) {//1.获取对应的class//   jclass      (*FindClass)(JNIEnv*, const char*);     jclass clazz = (*env)-> FindClass(env, "com/jk184/cj/MainActivity" );//2.获取对应的方法     //c语言是获取方法的id//   jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);     jmethodID jmID = (*env)-> GetMethodID(env, clazz, "jkShow",               "(Ljava /lang/String;)V" );//3.执行方法//     void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);     (*env)-> CallVoidMethod(env, jobj, jmID,              (*env)-> NewStringUTF(env, "这是c反射调用java方法" ));}


注意:
(*env)-> GetMethodID(env, clazz, "jkShow",               "(Ljava /lang/String;)V" );
最有一个参数是方法的签名,具体规范百度。
可在bin/classes下执行javap -s 类名(com.jk184.cj.MainActivity) 获得类下面所有方法的签名。

(*env)-> CallVoidMethod(env, jobj, jmID,              (*env)-> NewStringUTF(env, "这是c反射调用java方法" ));
最后一个使用字符串,需要注意两点:
1.不能直接使用字符串 (c和java的类型不一致)
2.使用中文要注意c文件是UTF-8编码。(否则乱码报错)


第一次写csdn,初学jni,请抱着怀疑的心态看此文。
最后有错请指教...
1 0
原创粉丝点击