入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

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

创建时间:2016-03-04 投稿人: 浏览次数:642
如何通过JNI传递对象执行回调 JNI的全称是java native interface,用来调用某些特定于系统平台或者硬件的操作,但是它只能调用c/c++的代码,若是其它语言代码,只能通过c/c++进行二次调用。 关于JNI的完整技术文档,大家可以查看下面这个网址: http://java.sun.com/j2se/1.5.0/docs/guide/jni/   下面我们看下JNI如何执行回调函数: 我们知道在c/c++回调函数可以通过函数指针执行,但是在Java中已经没有指针的概念,在这里,我们先传递一个类对象给native函数,然后再dll中调用期望的函数即可。 下面的这个例子中,我们通过回调传递一个字符串给java,这在java和c/c++混合编程时传递dll内部的出错或其他信息到java层是很有用的。 1.  首先创建一个java类文件,封装一个native函数和一个用于回调的函数 package jni;

public class Log{

    static{
              System.loadLibrary("mylib");
    }
    
        //用来回调,输出c代码层的信息
    public void output(String out){
               System.out.println(out);
    }
    
        //native函数,用来传递对象
       public native void test(Log log);
    
    public static void main(String[] args){
        Log log = new Log();
        
        log.test(log);    
    }
} 2.  调用javah命令,生成对应的c/c++都文件 /* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jni_Log */

#ifndef _Included_jni_Log
#define _Included_jni_Log
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     jni_Log
 * Method:    test
 * Signature: (Ljni/Log;)V
 */
JNIEXPORT void JNICALL Java_jni_Log_test
  (JNIEnv *, jobject, jobject);

#ifdef __cplusplus
}
#endif
#endif
3.  利用vc和生成的头文件完成一个dll         #include <windows.h>

#include "jni_Log.h"

int WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReasion,PVOID pvReserved)
{
    return TRUE;
}

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

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

                "i am a error!"。

声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。