写点什么

Java 的这个强大功能,很多人都不知道

发布于: 1 小时前

​​​​​​摘要:大多数框架采用单一的语言所开发。JNI 这项 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 技术

如何使用 JNI


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


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



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

开发 dll 动态链接库


下载 VS

使用 VS 开发 dll

VS 新建项目



输入项目名称



选择空项目,点击完成





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


#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 版本的,这点非常重要。




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



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


VS 生成的 dll 文件在哪个位置呢?别急,我们继续。


右击项目



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




开发 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 包下面,这样导入这个包的时候可以写绝对路径也可以写相对路径。



编写代码


注意:这里定义的接口方法名称需要和 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 方法,得到如下输出结果。



点击关注,第一时间了解华为云新鲜技术~

发布于: 1 小时前阅读数: 5
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
Java的这个强大功能,很多人都不知道