专栏首页全栈程序员必看如何通过JNI传递对象执行回调

如何通过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!“。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/100529.html原文链接:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 「音视频直播技术」JNI编程常见问题

    本文是JNI编程注意事项的第二篇文章。在上篇中讲解了 JavaVM/JNIEnv, Threads, jclass/jfieldID/jmethodID 以及 ...

    音视频_李超
  • Android JNI(一)——NDK与JNI基础

    Android 平台从一开就已经支持了C/C++了。我们知道Android的SDK主要是基于Java的,所以导致了在用Android SDK进行开发的工程师们都...

    隔壁老李头
  • JNI线程相关

    之前文章提到过JNIEnv是线程相关的,即在每一个线程中都有一个JNIEnv指针,每个JNIEnv都是线程专有的,其他线程不能使用本线程中的JNIEnv.

    小蚂蚁与大象
  • JNI 数据类型及Java与C++之间互调

    JNI,全称Java NativeInterface,是一种为Java编写本地方法和JVM嵌入本地应用程序标准的应用程序接口。

    Yif
  • JNI介绍

    JNI(Java Native Interface),即Java本地接口,JNI是Java调用Native 语言的一种特性。通过JNI可以使得Java与C/C+...

    小蚂蚁与大象
  • Android跨进程通信IPC之3——关于"JNI"的那些事

    在分析IPC基于Android 6.0)的过程中,里面的核心部分是Native的,并且还包含一些linux kernel,而作为Android开发者看到的代码大...

    隔壁老李头
  • 「音视频直播技术」JNI注意事项(一)

    Android手机现在已经占据全球智能手机市场第一位了。但Android手机广为大家所诟病的就是运行速度越来越慢。于是各App都在想尽办法进行优化,以提升用户感...

    音视频_李超
  • 如何通过反射调用对象的方法?

    唐怀瑟
  • Android基础--JNI

    Dalvik虚拟机加载C库时,即执行System.loadLibrary()函数时,第一件事是调用JNI_OnLoad()函数。可以在JNI_OnLoad 去注...

    小蚂蚁与大象

扫码关注云+社区

领取腾讯云代金券