java调用C++ dll以及代码联调
2016-11-02 15:34
288 查看
因为项目需要,为了节省开发时间,需要调用之前用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位)。
由于之前对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位)。
相关文章推荐
- Java调用C++动态链接库dll,有详细过程。VS2015+Eclipse以及失败解决方案
- Java调用C++动态链接库dll,有详细过程。VS2015+Eclipse以及失败解决方案
- [Java]Java中调用C/C++生成的DLL(转) (2007-05-16 23:51:44)
- java调用CC++编写的DLL文件问题
- Java Native Interface(Java 调用Delphi、C、C++编写的DLL)
- java调用c++封装的dll
- Java调用C++动态库dll
- Java调用dll与C++通讯(包括.dll文件的制作)
- __declspec(dllimport)和__declspec(dllexport)的区别,以及有关c/c++调用约定
- java 中System.loadLibrary()调用c++Dll的路径问题
- __declspec(dllimport)和__declspec(dllexport)的区别,以及有关c/c++调用约定
- java jni调用c/c++ dll
- Java中调用C/C++生成的DLL
- Java 多线程调用 C++ dll
- (转)__declspec(dllimport)和__declspec(dllexport)的区别,以及有关c/c++调用约定
- JAVA中调用C/C++生成的DLL
- Java调用Delphi DLL(通过C++调用和直接调用两种方式)
- java调用C/C++写的dll
- java调用c++写的dll 出现由于应该程序配置不正确,应用程序未能启动
- Windows 下java调用C++ dll动态链接库