日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

初识JNA

發布時間:2024/9/21 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 初识JNA 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

1.JNA簡介

????? JNA(Java Native Access)框架是一個開源的Java 框架,是SUN 公司主導開發的,建立在經典的JNI 的基礎之上的一個框架。JNA 項目地址:https://jna.dev.java.net/。

????? JNI 是Java 調用原生函數唯一的機制。JNA 也是建立在JNI 技術之上的,它簡化了Java調用原生函數的過程。使用JNA可以使你像調用java方法一樣直接調用本地方法,極大地擴展了java平臺的整合能力。

????? JNA 提供了一個動態的C 語言編寫的轉發器,可以自動實現Java 和C 的數據類型映射。

2.JNA調用原生函數示例

????? 假設libCms.dll動態鏈接庫中發布了如下C函數:

lc_init(string filename,Param param)

該函數作用是根據監聽參數啟動一個監聽,CmsListenParam具體是什么暫時不用管,后面會詳細介紹。為了調用這個原生函數,使用JNA,編寫如下java代碼:

private interface GetBroadcastIds extends Library {GetBroadcastIds INSTANCE = (GetBroadcastIds) Native.loadLibrary("LCAudioThrDll",GetBroadcastIds.class);int lc_init(String filename,Param param);}

然后我們就可以像調用java代碼一樣調用原生函數了:

public static void main(String[] args) {String filename = "D:\\KuGou\\體面.mp3";Param param = new Param();param.sethWnd(0L);//Windows窗口句柄,如果不為NULL,線程將事件消息發送到此窗口param.setPriority(0);//音頻流優先級0~255param.setCastMode(2);//播放方式,單播,組播和廣播[0,1,2]param.setVolume(80);//音量0~100param.setIP(3232261139L);//IP轉數字param.setTone(0);//音調(未使用)0~15param.setBass(200);//低音頻率0~3000param.setTreble(3000);//高音頻率200~20000param.setTrebleEn(0);//高音放大因子0~255param.setBassEn(0);//低音放大因子0~255param.setSourcType(0);//音頻數據源,0表示數據源為文件,1表示數據源為聲卡輸入[0,1,2,3]DDMineService.instance.lc_init(filename,param);System.out.println("調用成功"); }

3.JNA調用原生函數的模式

? ? JNA中使用Native關鍵字來聲明一個Java方法代表外部的原生函數,JNA不使用Native代表原生函數,而是使用java interface來代表動態鏈接庫中代表的所有原生函數,對于不使用的原生函數,可以不在interface中聲明原型。?

4.java和原生代碼的類型映射

????JNA 使用的數據類型是Java 的數據類型。而原生函數中使用的數據類型是原生函數的編程語言使用的數據類型。可能是C,Delphi,匯編等語言的數據類型。如數據類型映射不一致,在調用中可能會發生無法預知的行為,可能是調用不成功,也可能不能正確解析返回數據。????

????C#,java和操作系統數據類型對應表

C,java和操作系統數據類型對應表

native typesizejava typecommon windows types
char

?8-bit integer

byteBYTE, TCHAR
short16-bit integershortWORD
wchar_t16/32-bit characterchar

TCHAR

int32-bit integerint

DWORD

intboolean valuebooleanBOOL
long32/64-bit integerNativeLongLONG
long long64-bit integerlong

__int64

float32-bit FPfloat?
double64-bit FPdouble?
char*C stringStringLPTCSTR
void*pointerPointerLPVOID, HANDLE, LPXXX
pointer?Buffer/Pointer平臺依賴(32 或64 位指針)
pointer/array?<T>[] (基本類型的數組)32 或64 位指針(參數/返回值)
鄰接內存(結構體成員)
wchar_t*?WString\0 結束的數組(unicode)
char**?String[]\0 結束的數組的數組
wchar_t**?WString[]\0 結束的寬字符數組的數組
struct*/struct?Structure指向結構體的指針(參數或返回值) (或者明確指定是結構體指針)/結構體(結構體的成員) (或者明確指定是結構體)
union?Union等同于結構體
Structure[]?struct[]結構體的數組,鄰接內存
<T> (*fp)()?CallbackJava 函數指針或原生函數指針
varies?NativeMapped依賴于定義
pointer?PointerType和Pointer 相同

5.跨平臺、跨語言調用原則:
盡量使用基本、簡單的數據類型;
盡量少跨平臺、跨語言傳遞數據!
如果有復雜的數據類型需要在Java 和原生函數中傳遞,那么我們就必須在Java 中模擬
大量復雜的原生類型。這將大大增加實現的難度,甚至無法實現。
如果在Java 和原生函數間存在大量的數據傳遞,那么一方面,性能會有很大的損失。
更為重要的是,Java 調用原生函數時,會把數據固定在內存中,這樣原生函數才可以訪問這
些Java 數據。這些數據,JVM 的GC 不能管理,會造成內存碎片。
如果在你需要調用的動態鏈接庫中,有復雜的數據類型和龐大的跨平臺數據傳遞。那么
你應該另外寫一些原生函數,把需要傳遞的數據類型簡化,把需要傳遞的數據量簡化。

轉載于:https://my.oschina.net/u/4006148/blog/2252532

總結

以上是生活随笔為你收集整理的初识JNA的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。