使用JNA庫調(diào)用dll/so 動態(tài)庫

簡介:

JNA全稱:Java Native Access,是一款在JNI層做了封裝,為了簡捷方便讓開發(fā)者調(diào)用動態(tài)庫的開源庫钦睡。

流程:

  • 首先去JNA在GitHub中的主頁下載最新的jna核心 jar包何platform jar包拯钻,目前最新的是版本是jna-5.2.0、jna platform-5.2.0
  • 寫一個interface TestDll 繼承 jna包里面的 Library / StdCallLibrary 接口,代碼如下:
public interface TestDll extends Library{
   // 聲明一個實例棠众,加載動態(tài)庫并持有庫的引用
   String dllPath = "msvcrt";  //動態(tài)庫的路徑琳疏,如 window是系統(tǒng)自帶的msvcrt.dll【可不需要帶動態(tài)庫后綴,JNA庫會自動識別動態(tài)庫的類型】
   TestDll INSTANCE = Native.load(dllPath, TestDll.class);

  // 聲明一個方法闸拿,來映射native方法空盼,通過調(diào)用該方法實現(xiàn)調(diào)用native 方法,
 // 示例 msvcrt.dll中定義的一個void printf(String format, Object... objects)方法:
  void printf(String format, Object... objects)新荤;
}
  • 然后在Java代碼中調(diào)用printf()方法
public class Test{
    public static void main(String[] args){
        // 方式1:調(diào)用native printf()方法
        TestDll.INSTANCE.printf("Hello World");
        
       // 方式2:調(diào)用native printf()方法
      TestDll testDll = Native.load("msvcrt.dll", TestDll.class);
      testDll.printf("Hello World");
  }
}

入坑點:

  1. 關(guān)于JNA調(diào)用32位和64位動態(tài)鏈接庫揽趾,即*.dll


    影響JNA加載動態(tài)庫成功的因素
  2. 查找動態(tài)鏈接庫路徑的順序:

  • 先從當(dāng)前類的當(dāng)前文件夾找,
  • 如果沒有找到苛骨,再在當(dāng)前工程目錄中查找篱瞎,找到后搜索對應(yīng)的dll文件,-
  • 如果找不到痒芝,再到C盤 Windows目錄下面去查找(主要在System32俐筋、SysWOW64目錄中查找)
  • 再找不到就會拋異常
  1. Windows 64bit操作系統(tǒng),System32文件夾下的dll是64位版本的严衬,而SysWOW64文件夾下的dll其實是32位版本的
    注:SysWOW64 全稱:32bit Windows On 64bit Windows(64位Windows上的32位Windows)

  2. 有的c / c++語言定義的函數(shù)的參數(shù)用到了struct(結(jié)構(gòu)體)校哎,例如kernel32.dll庫里面的 void GetLocalTime()函數(shù):

typedef struct {
WORD wYear; 
WORD wMonth; 
WORD wDayOfWeek; 
WORD wDay; 
WORD wHour; 
WORD wMinute; 
WORD wSecond; 
WORD wMilliseconds; 
} SYSTEMTIME, *LPSYSTEMTIME;
VOID GetLocalTime(LPSYSTEMTIME lpst);

在Java中需要定義一個類繼承 jna包里面的Structure類,作為Java中的結(jié)構(gòu)體瞳步,代碼如下:

public static class SystemTime extends Structure {
        public short wYear;
        public short wMonth;
        public short wDayOfWeek;
        public short wDay;
        public short wHour;
        public short wMinute;
        public short wSecond;
        public short wMilliseconds;
        
        /*【關(guān)鍵坑點】:這里必須重寫getFieldOrder()方法闷哆,明確結(jié)構(gòu)體中涉及字段的名稱和聲明次序,
          為了確保執(zhí)行native方法单起,能正確的賦值內(nèi)容給各字段
          如果不這樣重寫抱怔,會報jna的一個異常
       */
        @Override
        protected List<String> getFieldOrder() {
            // TODO Auto-generated method stub
            System.out.println("重寫getFieldOrder()方法");
            return Arrays.asList("wYear","wMonth","wDayOfWeek","wDay","wHour","wMinute","wSecond","wMilliseconds");
          } 
       }


        @Override
        protected List<Field> getFieldList() {
            return super.getFieldList();
        }

    // 結(jié)構(gòu)體作為函數(shù)參數(shù)時,以引用(即指針)形式傳遞參數(shù)
    public static class ByReference extends CommData implements Structure.ByReference { }

    // 結(jié)構(gòu)體作為函數(shù)參數(shù)時嘀倒,以值傳遞形式傳遞參數(shù)
    public static class ByValue extends CommData implements Structure.ByValue{}

    // 聲明要調(diào)用native方法的一個方法接口
    void GetLocalTime(SystemTime result);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末屈留,一起剝皮案震驚了整個濱河市局冰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌灌危,老刑警劉巖康二,帶你破解...
    沈念sama閱讀 221,331評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異勇蝙,居然都是意外死亡沫勿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評論 3 398
  • 文/潘曉璐 我一進店門味混,熙熙樓的掌柜王于貴愁眉苦臉地迎上來产雹,“玉大人,你說我怎么就攤上這事翁锡÷冢” “怎么了?”我有些...
    開封第一講書人閱讀 167,755評論 0 360
  • 文/不壞的土叔 我叫張陵馆衔,是天一觀的道長瘟判。 經(jīng)常有香客問我,道長角溃,這世上最難降的妖魔是什么拷获? 我笑而不...
    開封第一講書人閱讀 59,528評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮开镣,結(jié)果婚禮上刀诬,老公的妹妹穿的比我還像新娘咽扇。我一直安慰自己邪财,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,526評論 6 397
  • 文/花漫 我一把揭開白布质欲。 她就那樣靜靜地躺著树埠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嘶伟。 梳的紋絲不亂的頭發(fā)上怎憋,一...
    開封第一講書人閱讀 52,166評論 1 308
  • 那天,我揣著相機與錄音九昧,去河邊找鬼绊袋。 笑死,一個胖子當(dāng)著我的面吹牛铸鹰,可吹牛的內(nèi)容都是我干的癌别。 我是一名探鬼主播,決...
    沈念sama閱讀 40,768評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼蹋笼,長吁一口氣:“原來是場噩夢啊……” “哼展姐!你這毒婦竟也來了躁垛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,664評論 0 276
  • 序言:老撾萬榮一對情侶失蹤圾笨,失蹤者是張志新(化名)和其女友劉穎教馆,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體擂达,經(jīng)...
    沈念sama閱讀 46,205評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡土铺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,290評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了谍婉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舒憾。...
    茶點故事閱讀 40,435評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖穗熬,靈堂內(nèi)的尸體忽然破棺而出镀迂,到底是詐尸還是另有隱情,我是刑警寧澤唤蔗,帶...
    沈念sama閱讀 36,126評論 5 349
  • 正文 年R本政府宣布探遵,位于F島的核電站,受9級特大地震影響妓柜,放射性物質(zhì)發(fā)生泄漏箱季。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,804評論 3 333
  • 文/蒙蒙 一棍掐、第九天 我趴在偏房一處隱蔽的房頂上張望藏雏。 院中可真熱鬧,春花似錦作煌、人聲如沸掘殴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奏寨。三九已至,卻和暖如春鹰服,著一層夾襖步出監(jiān)牢的瞬間病瞳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工悲酷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留套菜,地道東北人。 一個月前我還...
    沈念sama閱讀 48,818評論 3 376
  • 正文 我出身青樓设易,卻偏偏與公主長得像逗柴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子亡嫌,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,442評論 2 359