首页 > 代码库 > Music Studio项目心得--JNI实现C++调用JAVA

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:/project/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:/project/Cpp调用Java/Cpp调用Java

而在生成的exe中是E:/project/Cpp调用Java/

但因为VS2010的特性,它的工作文件夹不是exe所在文件夹,而是源代码所在文件夹,这就导致了

static char AppClass[] = "openomr/openomr/SheetMusic";

在加上工作文件夹组成的绝对路径错误,也就是真正导致FindClass失败的原因

小结:这个问题在非常诡异,须要在今后的开发中注意,不能再犯这样的低级错误了

 

哈哈,调用java方法成功了,我能够放松一下了。。。我去CF了。。。

 

 

 

Music Studio项目心得--JNI实现C++调用JAVA