Music Studio專案心得--JNI實現C++呼叫JAVA
這個專案是我參加內蒙古挑戰杯的比賽專案,由於時間關係,我沒時間實現OpenOMR開源專案由JAVA完全向C++的轉換,經過我半個多月的嘗試,我將OpenOMR中的1/3的程式碼改寫成C++,不過很快我就發現,如果按照這個進度,我是無論如何也無法按時完成工作了,更重要的是Joone人工智慧庫的演算法要是完全移植不是我一個大二學生能夠在這麼短的時間做到的,於是我放棄JAVA轉C++的解決方。
取而代之的是,我使用JAVA做演算法的核心,這樣就可以用最小的代價快速完成專案,而用C++去呼叫JAVA的方法,並封裝成dll,最後使用C# + IrisSkin2 + 自繪空間的方式製作介面並實現業務邏輯(不要認為C++的步驟多此一舉,實際上我的母語是C++,所以做起來非常順手,反而使我的效率大幅度提升)。
下面說一下我在實現C++呼叫JAVA的過程中遇到的一些問題。
開發環境: Visual Studio 2010 Ultimate (英文版) + eclipse 3.6.1 + JDK 1.6.0_10
眾所周知JAVA依賴jvm,而且執行起來非常繁瑣,我這個專案的命令列如下(批處理)
java -cp %cd%/joone-engine-2.0.0RC1/joone-engine.jar;%cd%/jfreechart-1.0.1/lib/jcommon-1.0.0.jar;.;%cd%/jfreechart-1.0.1/lib/jfreechart-1.0.1.jar -Xmx256m openomr.openomr.SheetMusic
不要說使用者看這東西會不知所措,就是我看著這東西也是很頭疼(雖然我很熟悉dos)
下面講一下技術難點:
一、不依賴使用者機器上的JAVA環境
解決方案:使用本地應用程式整合jre環境,脫離對客戶機器jre的依賴
遇見的問題:最開始的時候我認為只需要附帶jvm.dll即可實現我的目的,程式碼如下
我將jvm.lib和jvm.dll都放在Debug資料夾中,我發現這時的程式能正確載入jvm.dll,但是執行
JNICreateJavaVM createJavaVM = (JNICreateJavaVM)GetProcAddress(JVM_DLL, "JNI_CreateJavaVM");
就提示失敗了,為了解決這個問題我開始閱讀jni的文件,但是收效甚微,於是開始在各大技術論壇開始尋找解決方案,但是沒有找到解決方案,於是我將系統的jre中的jvm.dll載入到程式中,這次程式終於正常跑了起來。
小結:jvm.dll的執行依賴jre中許多dll,而我在專案初期只外掛一個jvm.dll導致了jvm無法正常建立,順便說一下,解決這個問題從下午5點一直到晚上接近十點才徹底解決,有時候人的慣性思維真的會限制住靈感。
技術難點二:帶有目錄結構的java類呼叫
這個糾結了小半天,直接貼程式碼了
期間遇到的主要問題就是在VS2010上除錯程式,始終FindClass查詢類失敗,為此試了各種辦法,先是呼叫jar,後來又把jar解壓。。。都沒有成功,於是乎。。。各種糾結。。。下午趕上騰訊的CF有活動,因此申請了個新QQ,去領了把M4A1-A + 防彈衣嘿嘿,小小的YD一下。。。晚上回來突然想法一個問題,就是VS2010的解決方案的目錄結構問題
先看一下我的測試專案的目錄結構-
大家注意,E:/工程/Cpp呼叫Java/Debug是可執行檔案生成的資料夾,我的庫也是直接放在了這個資料夾內,但是這就導致了一個問題,我的程式碼和exe不再同一個目錄,於是
static char ClassPath[] = "-Djava.class.path=./;E:/joone-engine-2.0.0RC1/joone-engine.jar;E:/jfreechart-1.0.1/lib/jcommon-1.0.0.jar;E:/jfreechart-1.0.1/lib/jfreechart-1.0.1.jar";
static char LibraryPath[] = "-Djava.library.path=./";
這裡面的”./“在原始碼中代表的路徑就是E:/工程/Cpp呼叫Java/Cpp呼叫Java
而在生成的exe中是E:/工程/Cpp呼叫Java/
但由於VS2010的特性,它的工作目錄不是exe所在目錄,而是原始碼所在目錄,這就導致了
static char AppClass[] = "openomr/openomr/SheetMusic";
在加上工作目錄組成的絕對路徑錯誤,也就是真正導致FindClass失敗的原因
小結:這個問題在很詭異,需要在今後的開發中注意,不能再犯這種低階錯誤了
哈哈,呼叫java方法成功了,我可以放鬆一下了。。。我去CF了。。。
相關文章
- C++庫封裝JNI介面——實現java呼叫c++C++封裝Java
- java呼叫c++動態庫之jni呼叫JavaC++
- Android JNI實現Java與C/C++互相呼叫,以及so庫的生成和呼叫(JNI方式呼叫美圖秀秀so)AndroidJavaC++
- Android Studio NDK開發-JNI呼叫Java方法AndroidJava
- android實現app通過jni呼叫C/C++方法AndroidAPPC++
- 關於一個java專案呼叫另一個java專案的心得Java
- Android Studio NDK開發:JNI呼叫Java函式AndroidJava函式
- Android Studio NDK:二、JNI 返回JAVA 實體AndroidJava
- android使用JNI呼叫C,C++程式AndroidC++
- Visual Studio容器專案工程化心得
- MediaScanner Java, JNI, mediaservice 呼叫關係Java
- JAVA JNI 呼叫C語言 DemoJavaC語言
- C語言 JNI 呼叫JAVA DemoC語言Java
- JNI:Java程式碼呼叫原生程式碼Java
- music-lake專案梳理
- Java大作業:AI千戀萬花(呼叫api實現)附專案)JavaAIAPI
- Vue 實現的音樂專案 music app 知識點總結分享VueAPP
- 專案管理培訓實踐心得專案管理
- Android studio jniAndroid
- 使用 Rust 語言編寫 Java JNI 實現RustJava
- Java如何呼叫C語言程式,JNI技術JavaC語言
- java實現分散式專案搭建Java分散式
- Java實現非同步呼叫Java非同步
- 使用 Java實現mTLS呼叫JavaTLS
- Android Studio 呼叫Camera實現拍照功能Android
- 技術積累——C++ 呼叫 python 專案C++Python
- Java的Panama專案與JNI以及外部函式介面FFIJava函式
- Android - JNI加入標準C++檔案AndroidC++
- AI千戀萬花(java呼叫api實現)附完整專案及註釋)重置版)AIJavaAPI
- 簡單實現Android NDK編譯jni呼叫動態庫開發Android編譯
- Android JNI開發系列之Java與C相互呼叫AndroidJava
- 設計模式Java實現開源專案設計模式Java
- Android Studio向專案新增C/C++原生程式碼AndroidC++
- JNI原始碼分析(並實現JNI動態註冊)原始碼
- C++非同步呼叫利器future/promise實現原理C++非同步Promise
- C、C++、Java?Java Native Interface(JNI)特輯——C反射java函式C++Java反射函式
- JNI開發系列③C語言呼叫Java欄位與方法C語言Java
- JNI實現圖片壓縮