快捷搜索:  汽车  科技

java独特的功能(Java的一个强大功能竟渐渐被遗忘)

java独特的功能(Java的一个强大功能竟渐渐被遗忘)为了能够让小伙伴们顺利的按照文章开发出自己的JNI程序,这里,我就详细的说下如何开发一个JNI程序,主要分三个大的方面来说明如何使用JNI技术调用C和C 写的程序。先说说使用JNI时有哪些坑吧,以避免小伙伴们重复踩坑,这里,大家需要注意的是:在使用JNI技术调用dll动态链接库时,32位dll只能是32位JDK去调用,64位dll只能是64位JDK去调用。这个必须是这样的,如果发现无法调用或者提示版本错误,首先要检查下JDK的位数和dll的位数是否是对应的。最近,冰河在分析500多TB的数据,从500多TB的数据中分析用户的行为习惯,以便为用户提供更好的产品体验和推荐更加适合用户的产品。然而,在实现算法的过程中,使用Java语言开发的算法从500多TB的数据中,单独分析某个用户某段时间的行为时,耗费了极大的时间开销。无论我如何优化算法,都不能达到预期的效果。很显然,这不符合性能要求。一名

java独特的功能(Java的一个强大功能竟渐渐被遗忘)(1)

大家好,我是冰河~~

说起java,简单好用,但是Java中很多牛逼的技术却逐渐被遗忘了~~

在Java语言出现之前,很多系统都是使用C和C 开发的。Java出现之后,由于其面向对象的思想更加符合人们的思维习惯,Java也不用像C和C 那样需要程序员手动管理内存的分配和回收。说白了,就是简单好用。由于Java的诸多优点,使其一跃霸榜编程语言前排很多年。

为了能够和使用C和C 写的程序进行交互,Java提供了本地方法的特性,也就是我们常说的JNI技术,然而,随着互联网的高速发展,分布式、微服务、大数据、云计算等技术和框架层出不穷,但大多数框架采用单一的语言所开发。JNI这项Java中提供的强大功能,却逐渐的被人遗忘了。

为何使用JNI

最近,冰河在分析500多TB的数据,从500多TB的数据中分析用户的行为习惯,以便为用户提供更好的产品体验和推荐更加适合用户的产品。然而,在实现算法的过程中,使用Java语言开发的算法从500多TB的数据中,单独分析某个用户某段时间的行为时,耗费了极大的时间开销。无论我如何优化算法,都不能达到预期的效果。很显然,这不符合性能要求。

一名小伙伴对我说:试试C语言嘛。对啊!我为啥不试试用C语言写算法啊,于是乎,使用C语言写了算法,经过不断的优化和调整,算是初步达到了算法性能要求。但是向数据大屏展示数据的时候,后端还是要以微服务的形式部署,于是我想到了Java中的JNI技术

注:后面单独写一篇我是如何分析500多TB数据的。

如何使用JNI

先说说使用JNI时有哪些坑吧,以避免小伙伴们重复踩坑,这里,大家需要注意的是:在使用JNI技术调用dll动态链接库时,32位dll只能是32位JDK去调用,64位dll只能是64位JDK去调用。这个必须是这样的,如果发现无法调用或者提示版本错误,首先要检查下JDK的位数和dll的位数是否是对应的。

为了能够让小伙伴们顺利的按照文章开发出自己的JNI程序,这里,我就详细的说下如何开发一个JNI程序,主要分三个大的方面来说明如何使用JNI技术调用C和C 写的程序。

java独特的功能(Java的一个强大功能竟渐渐被遗忘)(2)

注意:本文中我使用的是jna Java类库实现JNI开发。

开发dll动态链接库下载VS

小伙伴们可以在【冰河技术】公众号回复“vscode”,获取VS2010下载链接。

使用VS开发dll

VS新建项目

java独特的功能(Java的一个强大功能竟渐渐被遗忘)(3)

输入项目名称\

java独特的功能(Java的一个强大功能竟渐渐被遗忘)(4)

选择空项目,点击完成



java独特的功能(Java的一个强大功能竟渐渐被遗忘)(5)

java独特的功能(Java的一个强大功能竟渐渐被遗忘)(6)

创建完成后,将下面这段代码复制进去:

#include <windows.h> #include <iostream> #include <string> using std::string; using std::cin; using std::cout; using std::endl; #define MYLIBAPI extern "C" __declspec( dllexport ) //这的参数是必须的,也可以定义为.c头文件 MYLIBAPI double add(double a double b); MYLIBAPI double mul(double a double b); MYLIBAPI char * getString(char* a); double add(double a double b){ return a b; } double mul(double a double b){ return a*b; } //定义了一个返回java String类型的参数 char * getString(char* a){ char* b ="this is test"; return strcat(a b); } 复制代码

这里要注意的是:java的String和cpp的String不一样的,其对应的是char 如果要用cpp的string不是乱码就是调用失败。*

使用VS生成dll

这里变成Release,点击配置管理器配置x64版本,这样生成的dll就是x64版本的,这点非常重要

java独特的功能(Java的一个强大功能竟渐渐被遗忘)(7)

java独特的功能(Java的一个强大功能竟渐渐被遗忘)(8)

配置完成以后右击项目点击生成按钮。

java独特的功能(Java的一个强大功能竟渐渐被遗忘)(9)

这一顿操作下来,基本就能够正确的生成dll了,如果不能生成,极有可能是你的姿势不对,照着文章重新弄一遍,如果还是不行,你就加我微信问我吧。

VS生成的d

java独特的功能(Java的一个强大功能竟渐渐被遗忘)(10)

这里要注意的是在上级目录!不要想当然打开的项目位置然后直接就去x64去找了,根本没用!里面没有dll,是在上级目录,上级目录 的x64位置。

java独特的功能(Java的一个强大功能竟渐渐被遗忘)(11)

java独特的功能(Java的一个强大功能竟渐渐被遗忘)(12)

开发Java程序导入Maven依赖

新建Maven项目后,在Maven的pom文件中引入如下依赖。

<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna --> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.3.1</version> </dependency> <!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna-platform --> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> <version>5.3.1</version> </dependency> 复制代码指定dll位置

我个人就放在这个lib包下面,这样导入这个包的时候可以写绝对路径也可以写相对路径。

java独特的功能(Java的一个强大功能竟渐渐被遗忘)(13)

编写代码

注意:这里定义的接口方法名称需要和dll中的方法名称一致。

package com.binghe.jni; import com.sun.jna.Library; import com.sun.jna.Native; /** * @author binghe * @description: 测试JNI程序 */ public class JnaTest { public interface TestProject extends Library { TestProject INSTANCE = (TestProject) Native.load("src/main/lib/testDll.dll" JnaTest.TestProject.class); public double add(double i double j); public double mul(double i double j); public String getString(String a); } public static void main(String[] args) { System.out.println(TestProject.INSTANCE.add(20.11 20.0)); System.out.println(TestProject.INSTANCE.mul(16.9 20.89)); System.out.println(TestProject.INSTANCE.getString("我现在正在测试dllgihjb")); } } 复制代码运行Java程序

直接运行main方法,得到如下输出结果。


作者:冰_河
链接:https://juejin.cn/post/6986497976331927582
来源:掘金
著作权归作者所有。商业转载请联系作者获得

java独特的功能(Java的一个强大功能竟渐渐被遗忘)(14)

大功告成~~

好了,今天就到这儿吧,我们下期见~~


作者:冰_河
链接:https://juejin.cn/post/6986497976331927582
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

猜您喜欢: