1. 程式人生 > >jnaerator:java呼叫動態庫的神器,JNA程式碼自動生成工具

jnaerator:java呼叫動態庫的神器,JNA程式碼自動生成工具

眾所周知,java程式如果要呼叫動態庫(.so,.dll)的函式,最傳統方式是使用JNI技術,用JNI寫java呼叫介面程式碼是非常痛苦的,除錯也是比較麻煩的事兒,JNA推出後,大大降低了開發難度,java程式設計師只要為對應的動態庫定義java native方法程式碼,為對應的C資料結構寫出java物件,就可以了,不需要再為了呼叫動態庫而寫c/c++程式。
相比JNI,JNA是一個很大的進步,但java程式還是要寫一些java程式碼才能正確呼叫動態庫,動態庫函式涉及的所有結構型別都需要定義對應的java型別,如果結構型別比較多是個很大的工作量。
能不能更簡單一些呢?
最近正為寫呼叫動態庫的事兒頭痛,雖然我也會寫JNI程式碼,但實在太麻煩,總想找個捷徑,看了JNA相關資料後,發現用JNA所需要寫的相關java程式碼其實都是很有規則的。既然這樣,會不會有提供JNA程式碼生成的開源工具呢?

在google上七找八找的,居然找到了。這就是jnaerator
jnaerator是google貢獻的一個開源專案,用於生成基於JNA/BridJ的呼叫C/Object-C語言動態庫的java程式碼的程式碼生成工具。有了這個神器,你可以不需要為了呼叫動態庫而手工寫哪怕一行程式碼。
本文以實際舉例的方式,介紹jnaerator的簡單用法。
jnaerator可以命令列執行,也可以以maven外掛方式執行,本文只介紹命令列執行方式。

下載jar

JNA程式碼生成

如下圖目錄結構,有兩個dll,及相對應的標頭檔案,我們這兩個動態庫為例說明如何用jnaerator來生成全套JNA程式碼。

├─bin
│     THFeature.dll
│     THFaceImage.dll
└─include
       THFaceImage_i.h
       THFeature_i.h

命令列執行如下

java -jar d:\download\jnaerator-0.12-shaded.jar \
    -runtime JNA \
    -mode Maven \
    -mavenGroupId net.gdface \
    -mavenArtifactId cassdk_jna \
    -o jna_code
    -package net.gdface.jna
-f \ -library THFaceImage \ bin\THFaceImage.dll include\THFaceImage_i.h -library THFeature \ bin\THFeature.dll include\THFeature_i.h

引數說明:

  • -runtime JNA

    指定目標執行庫為JNA,
    -runtime 可選的值有(區分大小寫):

    • JNA
      JNAerator (based on JNA)
    • BridJ
      支援 C++庫
    • NodeJS
      但是實測發現使用BridJ 是有問題的,NodeJS沒試過
  • -mode Maven

    指定輸出模式為Maven
    -mode可選的值(區分大小寫):

    • Jar : JAR 生成jar包,可以使用-jar指定生成的jar包檔名
    • StandaloneJar : 生成包含所有依賴庫的jar ,可以使用-jar指定生成的jar包檔名
    • Directory : 生成程式碼到資料夾
    • Maven : 生成maven格式的專案(pom.xml)
    • AutoGeneratedMaven : 生成maven格式的專案(pom.xml),執行mave install 自動編譯生成jar包,不生成原始碼
  • -mavenGroupId net.gdface

    指定 maven專案的 groupId

  • -mavenArtifactId cassdk_jna

    指定 maven專案的 artifactId

  • -o jna_code

    指定輸出資料夾 jna_code

  • -package net.gdface.jna

    指定生成java程式碼的包名。如果不指定,則預設包名為 library name

  • -f

    生成程式碼時強制覆蓋已經存在的檔案

  • -library THFaceImage -library THFeature

    指定後面的動態庫的名稱(library name),在這裡為”THFeature.dll”,如果不指定則library name 為 標頭檔案名稱:‘THFeature_i’,
    NOTE:-library就是個狀態引數,只對其後面的檔名引數有效,所以這裡用兩次-library分別為THFeature_i.hTHFeature_i.h指定了不同的動態庫名稱

  • bin\THFeature.dll include\THFeature_i.h bin\THFeature.dll include\THFeature_i.h

    指定要生成程式碼的動態庫和對應標頭檔案,前後順序無關,可以不提供動態庫檔名稱,只需要.h檔案就可以生成JNA程式碼

生成的maven專案程式碼結構如下

J:\WORKSPACE.NEON\CASSDK54\CASSDK\CASSDK_WINDOWS_X86_64\JNA_CODE
│  pom.xml
│  
└─src
    └─main
        ├─java
        │  └─net
        │      └─gdface
        │          └─jna
        │                  EF_Param.java
        │                  FaceAngle.java
        │                  THFeatureLibrary.java
        │                  THFaceImageLibrary.java
        │                  THFI_FacePos.java
        │                  THFI_Param.java
        │                  THFI_Param_Ex.java
        │                  TH_Image_Data.java
        │                  
        └─resources
            └─lib
                └─win64
                        THFeature.dll
                        THFaceImage.dll

NOTE:如果生成程式碼時不提供bin\THFeature.dll,THFaceImage.dll,則生成的資料夾中沒有resource資料夾

參考資料