这个项目是我参加内蒙古挑战杯的比赛项目,由于时间关系,我没时间实现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了。。。

 

 

 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐