如何经过JNI传递对象执行回调

 
JNI的全称是java native interface,用来调用某些特定于系统平台或者硬件的操做,可是它只能调用c/c++的代码,如果其它语言代码,只能经过c/c++进行二次调用。
关于JNI的完整技术文档,你们能够查看下面这个网址:
 
下面咱们看下JNI如何执行回调函数:
咱们知道在c/c++回调函数能够经过函数指针执行,可是在Java中已经没有指针的概念,在这里,咱们先传递一个类对象给native函数,而后再dll中调用指望的函数便可。
下面的这个例子中,咱们经过回调传递一个字符串给java,这在java和c/c++混合编程时传递dll内部的出错或其余信息到java层是颇有用的。
1.  首先建立一个java类文件,封装一个native函数和一个用于回调的函数


  1. package jni;

  2. public class Log{

  3.     static{
  4.               System.loadLibrary("mylib");
  5.     }
  6.     
  7.         //用来回调,输出c代码层的信息

  8.     public void output(String out){
  9.                System.out.println(out);
  10.     }
  11.     
  12.         //native函数,用来传递对象

  13.        public native void test(Log log);
  14.     
  15.     public static void main(String[] args){
  16.         Log log = new Log();
  17.         
  18.         log.test(log);
  19.     }
  20. }

2.  调用javah命令,生成对应的c/c++都文件


  1. /* DO NOT EDIT THIS FILE - it is machine generated */
  2. #include <jni.h>
  3. /* Header for class jni_Log */

  4. #ifndef _Included_jni_Log
  5. #define _Included_jni_Log
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. /*
  10.  * Class: jni_Log
  11.  * Method: test
  12.  * Signature: (Ljni/Log;)V
  13.  */
  14. JNIEXPORT void JNICALL Java_jni_Log_test
  15.   (JNIEnv *, jobject, jobject);

  16. #ifdef __cplusplus
  17. }
  18. #endif
  19. #endif

 
3.  利用vc和生成的头文件完成一个dll


  1. #include <windows.h>

  2. #include "jni_Log.h"

  3. int WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReasion,PVOID pvReserved)
  4. {
  5.     return TRUE;
  6. }

  7. JNIEXPORT void JNICALL Java_jni_Log_test(JNIEnv * env, jobject obj, jobject log)
  8. {
  9.     jclass cls = (*env)->GetObjectClass(env, log);
  10.     jmethodID jmid = (*env)->GetMethodID(env, cls, "output", "(Ljava/lang/String;)V");
  11.     jstring info = (*env)->NewStringUTF(env, "i am a error!");
  12.     (*env)->CallVoidMethod(env,log, jmid,info);
  13.     (*env)->ReleaseStringUTFChars(env,info,(*env)->GetStringUTFChars(env, info, FALSE));
  14. }


     编译完成后,将mylib.dll放到与jni同级的目录中,运行命令java jni.Log,便可看到控制台成功打印信息css

                "i am a error!"。java

相关文章
相关标签/搜索