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

如何通过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函数和一个用于回调的函数
如何通过JNI传递对象执行回调
package
 jni;
如何通过JNI传递对象执行回调
如何通过JNI传递对象执行回调

public
 
class
 Log

{

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

如何通过JNI传递对象执行回调              System.loadLibrary(
mylib);
如何通过JNI传递对象执行回调    }

如何通过JNI传递对象执行回调    
如何通过JNI传递对象执行回调        
//用来回调,输出c代码层的信息
如何通过JNI传递对象执行回调
    public void output(String out){

如何通过JNI传递对象执行回调               System.out.println(out);
如何通过JNI传递对象执行回调    }

如何通过JNI传递对象执行回调    
如何通过JNI传递对象执行回调        
//native函数,用来传递对象
如何通过JNI传递对象执行回调
       public native void test(Log log);
如何通过JNI传递对象执行回调    
如何通过JNI传递对象执行回调    
public static void main(String[] args){

如何通过JNI传递对象执行回调        Log log 
= new Log();
如何通过JNI传递对象执行回调        
如何通过JNI传递对象执行回调        log.test(log);    
如何通过JNI传递对象执行回调    }

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

2.
  调用javah命令,生成对应的c/c++都文件
如何通过JNI传递对象执行回调


/* DO NOT EDIT THIS FILE – it is machine generated */

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

<
jni.h
>

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


/* Header for class jni_Log */

如何通过JNI传递对象执行回调
如何通过JNI传递对象执行回调#ifndef _Included_jni_Log
如何通过JNI传递对象执行回调#define _Included_jni_Log
如何通过JNI传递对象执行回调#ifdef __cplusplus
如何通过JNI传递对象执行回调extern 


C

 

{

如何通过JNI传递对象执行回调#endif
如何通过JNI传递对象执行回调
/*
如何通过JNI传递对象执行回调 * Class:     jni_Log
如何通过JNI传递对象执行回调 * Method:    test
如何通过JNI传递对象执行回调 * Signature: (Ljni/Log;)V
如何通过JNI传递对象执行回调 
*/

如何通过JNI传递对象执行回调JNIEXPORT 
void JNICALL Java_jni_Log_test
如何通过JNI传递对象执行回调  (JNIEnv 
*, jobject, jobject);
如何通过JNI传递对象执行回调
如何通过JNI传递对象执行回调#ifdef __cplusplus
如何通过JNI传递对象执行回调}


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

3.
  利用vc和生成的头文件完成一个dll
   
如何通过JNI传递对象执行回调   
#include 
<
windows.h
>

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


jni_Log.h


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

int
 WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReasion,PVOID pvReserved)
如何通过JNI传递对象执行回调


{

如何通过JNI传递对象执行回调    
return TRUE;
如何通过JNI传递对象执行回调}


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

void
 JNICALL Java_jni_Log_test(JNIEnv 
*
 env, jobject obj, jobject log)
如何通过JNI传递对象执行回调


{

如何通过JNI传递对象执行回调    jclass cls 
= (*env)->GetObjectClass(env, log);
如何通过JNI传递对象执行回调    jmethodID jmid 
= (*env)->GetMethodID(env, cls, output(Ljava/lang/String;)V);
如何通过JNI传递对象执行回调    jstring info 
= (*env)->NewStringUTF(env, i am a error!);
如何通过JNI传递对象执行回调    (
*env)->CallVoidMethod(env,log, jmid,info);
如何通过JNI传递对象执行回调    (
*env)->ReleaseStringUTFChars(env,info,(*env)->GetStringUTFChars(env, info, FALSE));
如何通过JNI传递对象执行回调}


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

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

                i am a error!“。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 跨域与跨域访问_如何实现跨域访问

    跨域与跨域访问_如何实现跨域访问什么是跨域跨域是指从一个域名的网页去请求另一个域名的资源。比如从www.baidu.com页面去请求www.google.com的资源。跨域的严格一点的定义是:只要协议,域名,端口有任何一个的不同,就被当作是跨域为什么浏览器要限制跨域访问呢?原因就是安全问题:如果一个网页可以随意地访问另外一个网站的资源,那么就有可能在客户完全不知情的情况下出现安全问题。比如下面的操作就有安全问题

    2022年10月1日
    3
  • C#数组–(一维数组,二维数组的声明,使用及遍历)

    C#数组–(一维数组,二维数组的声明,使用及遍历)数组:是具有相同数据类型的一组数据的集合。数组的每一个的变量称为数组的元素,数组能够容纳元素的数称为数组的长度。一维数组:以线性方式存储固定数目的数组元素,它只需要1个索引值即可标识任意1个数组元素

    2022年7月2日
    23
  • Maven压缩插件YUI Compressor使用介绍

    Maven压缩插件YUI Compressor使用介绍简介这篇文章主要介绍了Maven压缩插件YUICompressor使用介绍以及相关的经验技巧,文章约18810字,浏览量165,点赞数5,值得参考!使用这个插件主要有两个作用:减少资源文件体积,提高移动端页面加载速度。对关键的前端代码进行一定的代码混淆,保护知识产权。使用说明:使用YUICompressor压缩JS和CSS。需要Maven2.0及以上工程。默认情…

    2022年7月18日
    33
  • win10无法生成常规子目录下的列表_windows无法更新怎么办

    win10无法生成常规子目录下的列表_windows无法更新怎么办1.问题背景Win10只要系统安装好之后会自动生成一系列的系统文件夹,如下:这类文件夹比较特殊,它们比普通文件夹多一个“位置”选项卡,如默认的“下载”文件夹,edge和chrome浏览器会默认下载到这个文件夹,所以新系统拿到手之后,往往都需要将这些文件夹修改到其他硬盘上,不然C盘会因为下载文件的不断增多而变得异常臃肿:如果这个时候你手抖了,需要修改……………

    2022年9月18日
    3
  • Celer cBridge 主网上线:无缝桥接跨链和跨层流动性

    Celer cBridge 主网上线:无缝桥接跨链和跨层流动性CelercBridgev1.0版本今天正式主网上线!用户可以立即使用cBridge在Ethereum、Arbitrum、BinanceSmartChain以及Polygon进行高速低成本跨链和跨层转账。cBridge将会在短期内支持更多的layer2和layer1区块链的跨链转账。此外,任何人都将能够通过运行cBridge节点加入cBridge网络以提供跨链跨层流动性,同时通过收取手续费产生收益。cBridge是一个重要的里程碑,它标志着Celer将在未来的多链多层区块链扩容生态下,提..

    2022年6月4日
    26
  • vue单页应用和多页应用_多页面应用需要vuejs吗

    vue单页应用和多页应用_多页面应用需要vuejs吗进入一家新的公司,要开发移动端app项目,前端技术选型时前端组长选的是vue的多页面开发,当时很蒙,vue不是单页面开发吗?咋出来多页面的。接触之后才发现确实存在也挺简单的,省去了路由表的配置。那就给大家整体思路分析一波吧。不足之处还请包涵!单页面开发我就不多说了,主要讲多页面的开发模式与最终效果,网上一搜单页面会有好多文章博客,但是搜多页面的就很少了,比如下面这个就是列了一下两种开发模式的优缺点。首先多页开发,肯定是一个页面就是一个单独文件,每个文件也有自己的.vue.js和comp.

    2022年10月13日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号