自上個月20號,歷時整整一個月,終於找到工作入職了。
然后這段時間一直看公司的框架還有業務方面的東西。其實由於給分配了一個研究Java調用C語言接口的問題,導致框架業務方面的東西還不熟,然后現在手上又有了一個需求要15號前做出來,感覺有點壓力啊。雖然說是和之前某個需求差不多,修修改改就能出來,但是這樣的話有點和我准備好再做事的性格沖突了。廢話說了一堆,就當是吐槽吧,這段時間都沒能好好看之前看到Java書籍了,這樣不行啊!!!
五一之前幾天,組里領導突然讓我研究下關於Java調用C語言的問題,當時我是懵了的,畢竟算是公司新人而且還是行業新人,這個任務感覺有點突然。不過畢竟是領導說的,我總不能說不行吧,所以我就應承下來了。之后我就網上各種搜索了。剛開始看到的說的都是JNI(java native interface),看了看感覺還行啊不是很難,然后就模仿寫了一個小demo。具體代碼就不貼了,比較簡單,就貼一個之前看的博客地址。JAVA中調用C語言接口
本來在公司寫過一個小文檔了,然而公司的保密政策讓我也不確定把我自己寫的文檔發我自己郵箱會不會違規......所以干脆就這樣吧
之前完成這個后,興奮的把小文檔發給了領導,沒想到之后就收到一個更大的任務,要讓我用Java實現去調用一個C語言編寫的SDK。那SDK函數都幾十個的感覺,雖然后來給精簡了下,留下不可缺少的9個函數和1個37個變量還是40+變量的結構體以及幾個靜態常量。
當時的我內心其實是崩潰的,因為在學習JNI的時候就發現其實處理指針和結構體是挺麻煩的...所以當時收到任務時,我也是先應承了下來,之后就又繼續搜索,最后給我發現了JNA開源類庫,官方github地址JNA。說是sun公司提供的建立在JNI之上的類庫。
之后經過一陣學習踩坑后,還是如期的完成的了任務。依然還是公司的保密政策,所以之前在公司寫的幾個坑只能先按印象寫了。
1、Native.loadLibrary("msvcrt", CLibrary.class);其中msvcrt是要加載的dll文件,這個文件一般是放在windows下的system32文件夾下,或者是jdk文件夾里的bin文件夾下面。但是前面兩個都比較麻煩,所以這個dll也可以加上路徑名,比如“C:\\msvcrt”。
2、當遇到C語言里面的方法有被“__stdcall”修飾的,那么就要寫成public interface Kernel32 extends StdCallLibrary{}而不是public interface Kernel32 extends Library{},否則據說會遇到崩潰。
3、在做Java調用SDK的工程時分成了4個文件,一個是專門放映射靜態常量的,一個是專門放映射結構體的,一個是專門放映射方法的,一個是測試類。
4、通過JNA傳遞數值時,最大的問題就是數據類型的轉換。比如C里面的long,unsign long,int都能用Java里的int映射,這里有個官方的映射表Default Type Mappings,個人覺得,C里面的char*用Java里面的byte[]來映射比較好,因為SDK任務里面,用String出錯了,byte[]就沒問題。另外還有一點需要注意的是,C和Java之間的傳值,應該是不支持二維數組的,或者說是不能直接用二維數組的,就是說不能用Java里面的byte[][]來映射C里面的char[][]。其解決方式是用間接的二維數組來映射。比如說C里面有個char[][]需要映射,則Java里面對應的是erweishuzu[],而erweisuzu的定義其實就是byte[]。
5、在運行測試類時,如果出現不能加載路徑正確且存在的dll文件,那么有可能是沒有把所有依賴的dll放在一起,可以同depend.exe查看dll文件所依賴的其它dll文件,放在一起后一般就能加載了。
暫時應該就是這些,其它的想到了再補充!