在Java語言出現(xiàn)之前,很多系統(tǒng)都是使用C和C++開發(fā)的。Java出現(xiàn)之后,由于其面向?qū)ο蟮乃枷敫臃先藗兊乃季S習(xí)慣,Java也不用像C和C++那樣需要程序員手動管理內(nèi)存的分配和回收。說白了,就是簡單好用。由于Java的諸多優(yōu)點,使其一躍霸榜編程語言前排很多年。
為了能夠和使用C和C++寫的程序進行交互,Java提供了本地方法的特性,也就是我們常說的JNI技術(shù),然而,隨著互聯(lián)網(wǎng)的高速發(fā)展,分布式、微服務(wù)、大數(shù)據(jù)、云計算等技術(shù)和框架層出不窮,大多數(shù)支持多語言的框架基本上都是都過RPC或者Restful API進行調(diào)用。JNI這項Java中提供的強大功能,卻逐漸的被人遺忘了。
圖片
最近,冰河在分析500多TB的數(shù)據(jù),從500多TB的數(shù)據(jù)中分析用戶的行為習(xí)慣,以便為用戶提供更好的產(chǎn)品體驗和推薦更加適合用戶的產(chǎn)品。然而,在實現(xiàn)算法的過程中,使用Java語言開發(fā)的算法從500多TB的數(shù)據(jù)中,單獨分析某個用戶某段時間的行為時,耗費了極大的時間開銷。無論我如何優(yōu)化算法,都不能達(dá)到預(yù)期的效果。很顯然,這不符合性能要求。
一名小伙伴對我說:試試C語言嘛。對啊!我為啥不試試用C語言寫算法啊,于是乎,使用C語言寫了算法,經(jīng)過不斷的優(yōu)化和調(diào)整,算是初步達(dá)到了算法性能要求。但是向數(shù)據(jù)大屏展示數(shù)據(jù)的時候,后端還是要以微服務(wù)的形式部署,于是我想到了Java中的JNI技術(shù)
注:后面單獨寫一篇我是如何分析500多TB數(shù)據(jù)的。
先說說使用JNI時有哪些坑吧,以避免小伙伴們重復(fù)踩坑,這里,大家需要注意的是:在使用JNI技術(shù)調(diào)用dll動態(tài)鏈接庫時,32位dll只能是32位JDK去調(diào)用,64位dll只能是64位JDK去調(diào)用。這個必須是這樣的,如果發(fā)現(xiàn)無法調(diào)用或者提示版本錯誤,首先要檢查下JDK的位數(shù)和dll的位數(shù)是否是對應(yīng)的。
為了能夠讓小伙伴們順利的按照文章開發(fā)出自己的JNI程序,這里,我就詳細(xì)的說下如何開發(fā)一個JNI程序,主要分三個大的方面來說明如何使用JNI技術(shù)調(diào)用C和C++寫的程序。
圖片
注意:本文中我使用的是jna Java類庫實現(xiàn)JNI開發(fā)。
圖片
圖片
選擇空項目,點擊完成
圖片
圖片
圖片
創(chuàng)建完成后,將下面這段代碼復(fù)制進去:
#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 ) //這的參數(shù)是必須的,也可以定義為.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類型的參數(shù)char * getString(char* a){ char* b ="this is test"; return strcat(a,b);}
這里要注意的是:java的String和cpp的String不一樣的,其對應(yīng)的是char,如果要用cpp的string不是亂碼就是調(diào)用失敗。
這里變成Release,點擊配置管理器配置x64版本,這樣生成的dll就是x64版本的,這點非常重要。
圖片
圖片
配置完成以后右擊項目點擊生成按鈕。
圖片
這一頓操作下來,基本就能夠正確的生成dll了,如果不能生成,極有可能是你的姿勢不對,照著文章重新弄一遍,如果還是不行,你就加我微信(hacker_binghe)問我吧。
VS生成的dll文件在哪個位置呢?別急,我們繼續(xù)。
圖片
這里要注意的是在上級目錄!不要想當(dāng)然打開的項目位置然后直接就去x64去找了,根本沒用!里面沒有dll,是在上級目錄,上級目錄 的x64位置。
新建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>
我個人就放在這個lib包下面,這樣導(dǎo)入這個包的時候可以寫絕對路徑也可以寫相對路徑。
注意:這里定義的接口方法名稱需要和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("我現(xiàn)在正在測試dllgihjb")); }}
直接運行main方法,得到如下輸出結(jié)果。
本文鏈接:http://www.tebozhan.com/showinfo-26-73794-0.html我敢說:99.9%的程序員根本沒在項目中使用過Java的這個功能!
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com