java调用C++ dll以及代码联调

来源:互联网 发布:新闻联播配音软件 编辑:程序博客网 时间:2024/06/06 13:22

因为项目需要,为了节省开发时间,需要调用之前用C++封装的一个dll。

由于之前对java不是很熟,实现过程中遇到许多问题,耽误了不少时间,在此记录。

主要参考http://www.iteye.com/topic/295776里边的方法,按照这个帖子里的方式顺路的话也可以成功。

步骤:

1.首先安装jdk1.6(不是jre,jre缺少jni库)和eclipse,由于C++的dll是32位的,为了保持一致,这里安装的版本也是32位。(如果不一致,可能导致无法加载dll)

注:由于之前安装jmeter做性能测试,安装了64位的jdk,需要重新修改环境变量JAVA_HOME以及PATH

2.在eclipse新建package,然后新建class,编写java的接口,如下所示

package zt;public class Test {// 接口    public native boolean ConnectDB( String ip, String port, String dbName, String user, String password);      public native boolean Do(String strPath);      public native void CloseDB();         // 加载dll    static {          System.loadLibrary("Test");      }              public static void main(String[] args) {           //System.out.println(System.getProperty("java.library.path"));        // 调用测试代码      Test test = new Test();           boolean bConnect = test.ConnectDB("192.168.1.62","5432","postgres","postgres","123");           if(!bConnect)          {        // 关闭数据库          test.CloseDB();            return;          }          boolean bOK = test.Do("E:/04_Data/test.jpg");          if(bOK)          {          // 进行相应操作          }                    // 关闭数据库          test.CloseDB();    }  }

保存或者编译,即可得到在工程目录的bin目录下得到对应的.class文件。


3.cmd命令行,cd进入工程class文件对应的目录,调用javah -classpath . -jni zt.Test,即可生成对应C++的头文件zt_Test.h


4.利用vs新建dll项目,配置需要包含的include以及lib,我这个主要对数据库连接,就需要配置数据库的头文件和库,不详述。

   然后将3中生成的zt_Test.h添加到该项目中,编写对应的cpp文件。同时,需要包含java的jni.h以及jni_md.h,这些文件在jdk安装目录的include文件夹中。


5.参数转换,如java的String转换后在c++中为jstring, 需要转换C++的const char*,如下所示,bool,int等类型不需转换

//Get the native string from javaString  const char *cstrIP = env->GetStringUTFChars(strIP, 0);  const char *cstrPort =  env->GetStringUTFChars(strPort, 0);const char *cstrDB =  env->GetStringUTFChars(strDBName, 0);const char *cstrUser =  env->GetStringUTFChars(strUser, 0);const char *cstrPassword =  env->GetStringUTFChars(strPassword, 0);//DON'T FORGET THIS LINE!!!  env->ReleaseStringUTFChars(strIP, cstrIP); env->ReleaseStringUTFChars(strPort, cstrPort); env->ReleaseStringUTFChars(strDBName, cstrDB); env->ReleaseStringUTFChars(strUser, cstrUser); env->ReleaseStringUTFChars(strPassword, cstrPassword); 


6.联调

       (1)将C++ 的dll以及其依赖的dll的目录添加环境变量PATH中;java中可以通过System.out.println(System.getProperty("java.library.path"));查看变量是否设置进去;注意,设置之后eclipse要重启。

注:同事说System.loadLibrary中也可添加绝对路径,但要该dll依赖的dll按顺序load,这个方法我没试。

        (2)如果System.loadLibrary("Test");报错,一般是由于C++的dll不对或者缺少依赖。

(3)在java中添加断点,然后打开C++的项目,在C++的相应代码处添加断点,然后再vs中,菜单“调试”-》“附近到进程”,找到javaw.exe选中,点击附加。

                  java中执行代码时,就可以在C++的断点出查看代码执行情况。


7.备注

实现过程尤其注意细节,如类名、环境变量的配置、dll的完整性以及编译的位数(32位、64位)。


  







   

0 0
原创粉丝点击