如何通过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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 比特币挖矿培训来到印度30个城市[通俗易懂]

    比特币挖矿培训来到印度30个城市[通俗易懂]点击上方“蓝色字”可关注我们!暴走时评:为了促进印度达利特阶层的商业企业发展,2005年印度成立了行业协会DICCI。Mahabfic则是在马哈拉施特拉邦宣传区块链、金融科技、ICO和加密货币投资的平台。最近两个机构合作在印度30个城市展开比特币挖矿培训,包括区块链技术、挖矿、创业、初创企业等课程内容。旨在为这些地区年轻人自主就业提供帮助,为这些地区创造新的经济增长点。作者:KevinHelms

    2022年5月28日
    44
  • MySQL的时间差函数TIMESTAMPDIFF、DATEDIFF的用法「建议收藏」

    MySQL的时间差函数TIMESTAMPDIFF、DATEDIFF的用法「建议收藏」MySQL的时间差函数TIMESTAMPDIFF、DATEDIFF的用法时间差函数TIMESTAMPDIFF、DATEDIFF的用法我们在写sql语句,尤其是存储过程中,会频繁用到对于日期、时间的比较和判断,那么对于这两个时间差比较函数用法做一个举例介绍。datediff函数,返回值是相差的天数,不能定位到小时、分钟和秒。–相差2天selectdatediff(‘2018-03-2209:…

    2022年6月13日
    47
  • SQL模糊查询语句(like)

    SQL模糊查询语句(like) 确定给定的字符串是否与指定的模式匹配。模式可以包含常规字符和通配符字符。模式匹配过程中,常规字符必须与字符串中指定的字符完全匹配。然而,可使用字符串的任意片段匹配通配符。与使用=和!=字符串比较运算符相比,使用通配符可使LIKE运算符更加灵活。如果任何参数都不属于字符串数据类型,MicrosoftSQLServer会将其转换成字符串数据类型(如果可能)。语法mat

    2022年5月26日
    175
  • java 排序队列_java实现顺序队列

    java 排序队列_java实现顺序队列packagequeue;importjava.util.Scanner;publicclassArrayQueueLoop{publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstub//测试代码//测试数组循化队列CircleQueuetestQueue=newCircleQueue(4);//设置的是有效…

    2022年7月16日
    17
  • Request对象接收Form表单提交[通俗易懂]

    Request对象接收Form表单提交[通俗易懂]转自:http://www.cnblogs.com/xdp-gacl/p/3798347.htmlForm表单:   HTML的form表单Html的Form表单元素编  号(文本框):size=”2″maxlength=”2″>用户名(文本框):密  码(密码框):性 

    2022年5月27日
    36
  • SecureCRT中文乱码解决方法(6)

    SecureCRT中文乱码解决方法(6)1、重新查看会话,是否中文显示正常2、依然无法正常显示中文,可能是由于Linux系统中默认的字符编码非UTF8所致用root用户登录。输入cat/etc/sysconfig/i18n如果安装系统为中文系统,则修改【LANG=“zh_CN.UTF-8”】如果安装系统为英文系统,则修改【LANG=“en_US.UTF-8”】保存文件。断开SSH,重新登录。就正常了下面是修改…

    2022年7月17日
    20

发表回复

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

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