大家好,我是冰河~~

说起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++写的程序。

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

开发dll动态链接库

下载VS

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

使用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方法,得到如下输出结果。

大功告成~~

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

Java中一个逐渐被遗忘的强大功能,强到你难以置信!!的更多相关文章

  1. java中一个字符串是另外一个字符串的字串

    java中一个字符串是另外一个字符串的字串 String类中有一个方法 public boolean contains(Sting s)就是用来判断当前字符串是否含有参数指定的字符串例s1=“take ...

  2. java中一个引人深思的匿名内部类

    前两天去面试javaweb问到一个问题,在你的项目中有没有用到线程,我特么的一想,这东西不是在c层面的吗,所以说我不了解线程..... 后来回去想啊想啊,我操这特么的不是再问我事物的控制,消息队列的回 ...

  3. java中一个重要思想:面向对象

    面向对象: 1, 面向过程的思想(合适的方法出现在合适的类里面) 准备去一个地方: 先买车, 挂牌, 开导航, 踩油门, 过黄河, 穿越珠穆朗玛峰... 2, 面向对象的思想 我开着车去, 车怎么去随 ...

  4. Java中一个线程只有六个状态。至于阻塞、可运行、挂起状态都是人们为了便于理解,自己加上去的。

    java中,线程的状态使用一个枚举类型来描述的.这个枚举一共有6个值: NEW(新建).RUNNABLE(运行).BLOCKED(锁池).TIMED_WAITING(定时等待).WAITING(等待) ...

  5. 为什么Java中一个char能存下一个汉字

    在Java中,char的长度是2字节,即16位,2的16次方是65536. 1.如果采用utf-8编码,一个汉字占3个字节,char为什么还能存下一个汉字呢? 参考:https://developer ...

  6. java中一个数组不能放不同数据类型的值

    在java中,数组不能放不同数据类型的值. 方法一: 多态 定义数组类型的时候定义为父类,而存进数组为父类的子类 public class test2 { public static void mai ...

  7. java中四种引用类型(对象的强、软、弱和虚引用)

    对象的强.软.弱和虚引用在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK 1.2 ...

  8. java中Number Type Casting(数字类型强转)的用法

    4.5 Number Type Casting(数字类型强转)隐式 casting(from small to big) byte a = 111; int b = a;显式 casting(from ...

  9. java中的四种引用方式(强引用,软引用,弱引用,虚引用)

    java内存管理主要有内存分配和内存回收,都不需要程序员负责,垃圾回收的机制主要是看对象是否有引用指向该对象. java中对象的引用主要有四种:强引用,软引用,弱引用,虚引用. Java中提供这四种引 ...

  10. java中一个查询业务的流程

    因为有用到分页,首先建一个page类 1 public class Page<T> { 2 private int pageSize; //每页显示条数 3 private int cur ...

随机推荐

  1. Sunnyui画曲线溢出错误

    之前用sunnyui做展示数据库数据曲线的时候.偶然会报溢出错误,也不报错错误在哪,就是直接程序都跑不动了. 后面发现 设置曲线上下限的时候,当上下限一样的时候就会导致溢出错误.sunnyui的曲线也 ...

  2. NC19782 Tree

    题目链接 题目 题目描述 修修去年种下了一棵树,现在它已经有n个结点了. 修修非常擅长数数,他很快就数出了包含每个点的连通点集的数量. 澜澜也想知道答案,但他不会数数,于是他把问题交给了你. 输入描述 ...

  3. display的值及作用

    display的值及作用 display属性可以设置元素的内部和外部显示类型,元素的外部显示类型将决定该元素在流式布局中的表现,例如块级或内联元素,元素的内部显示类型可以控制其子元素的布局,例如gri ...

  4. Annotation-specified bean name conflicts with existing

    问题说明 Annotation-specified bean name conflicts with existing,non-compatible bean definition of same n ...

  5. 【Android逆向】破解看雪9月算法破解第二题

    1. apk安装到手机,一样的界面,随便输入一样的报错 2. apk拖入到jadx重看看 public native String sha1(String str); static { System. ...

  6. 麒麟系统开发笔记(六):安装QtCreator开发IDE中的中文输入环境Fcitx输入法

    前言   中文输入法,QtCreator中无法输入中文也是ubuntu中一个常规问题,在麒麟系统中也此问题,要解决此问题,主要是安装和使用Fcitx输入法.  本文章最终结果是失败的,但是读者的系统未 ...

  7. click模块解析命令行参数

    click模块解析命令行参数 安装 pip install click 操作步骤 1)使用@click.command()装饰一个函数,使之成为命令行接口 2)使用@click.option()等装饰 ...

  8. 初始pyqt5

    开发pyqt5桌面应用 必须使用两个类:QApplication和QWidget.都在PyQt5.QtWidgets中 安装 pip install pyqt5 -i https://pypi.dou ...

  9. docker中container相关命令

    1.以tomcat镜像为例运行tomcat容器(运行tomcat实例) docker run tomcat 2.宿主机端口与容器端口进行映射 -p docker run -p 8080(系统上外部端口 ...

  10. NodeJS开启GZIP功能

    gzip是用于压缩,效果特别好,js.css等文件的压缩率一般高达70% 具体方法如下: 先安装一个依赖 npm install compression --save 然后在已有代码里(一般是app. ...