Java采用JNI调用VC++生成的dll(Java与C++交互)

应项目需求,需要android调用java,java再调用C++实现android一个图片匹配的功能,我们作为java组需要和C++和Android进行交互。下面是java和C++采用JNI的方式进行接口传参交互,我做的一个demo并运行成功。

什么是JNI?

JNI全拼是Java Native Interface,中文意思为Java本地调用。JNI标准是Java平台的一部分,它允许java和其他语言的代码进行交互。JNI开始是为了本地已经编译好的语言,尤其是C和C++而设计的,我们也可以使用JNI和其他语言进行沟通,我们只要调用约定受支持了就可以了。

什么原理?

我们知道C++中或者C#等.net都能生成.dll类库,而C++(或.net)中生成的.dll文件,相当于我们java程序中java源代码通过编译生成的.class文件,我们在java程序中直接通过code调用C++的dll文件即可。

在C语言中如果生成一个动态链接库dll文件的时候,需要两部分,一部分是为.h的头文件,这个文件是负责对一些方法的声明,而.cpp文件负责对方法的实现。而在java中,在JDK安装目录的include包中有个jni.h和jni_md.h,这个可以说是java发布的一个接口,在C++中可以直接使用这两个head类型的文件对java要调用的C++方法编译,让java调用,并可以接收java传递过来的参数。直接上代码啦。

具体的步骤如下所示(java发布一个接口,让C++实现乘法的功能)

1、建立java源代码如下所示。

建立java project,在src下建立com包,在com包下面建立我们的java类Reliability.java,代码如下所示。

package com;
public class Reliability {
	static {
		try {
			System.loadLibrary("Reliability"); // call dll
		} catch (UnsatisfiedLinkError e) {
			System.out.println("The load problem");
		}

	}
	public native int shanfei(int i);
	public static void main(String[] args) {
		Reliability reliability = new Reliability();
		System.out.print(reliability.shanfei(6));
	}
}

2、编译.java源文件。

我们想实现传递int 整型参数来实现自己和自己相乘的结果,而实现shanfei(int p)方法的是C++。我们可以通过System.loadLibrary("Reliability")方法实现加载C++生成的dll,通过native声明方法接口以及参数。

编写好自己的Reliability.java代码后,可以使用MyEclipse编译为Reliability.class文件或者是直接用javac命令编译为.class文件。

我的使用的MyEclipse进行编译的,会在/Reliability/bin/com文件夹中生成Reliability.class文件。

3、用javah 命令让Reliability.class文件生成C++需要的.h文件,也就是交给C++的接口。

在这里需要注意的是,一定要转到你编译成class文件的上一级目录进行javah命令,并且你的JDK已经配置好环境变量,这里的环境变量为JAVA_HOME:安装jdk bin文件夹的上一级目录,比如我的jdk安装在C:\java\bin....,那我的JAVA_HOME为:C:\java 。path目录:引用JAVA_HOME并且加上\bin
,为 %JAVA_HOME%\bin 。classpath为: .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;这是一定要配置好的。然后在dos窗口如下编写如下命令,生成给C++ .h的文件。

这样在你的class文件上一级目录中就会出现.h 的文件,并且引入到你的MyEclipse中,与com包同级。

4、这样java已经给C++发布好了com_Reliability.h的头文件,C++要去实现这个方法了。

因为要生成dll文件,所以我们需要建立动态链接库文件,如果用的是C++ 6.0环境,就是建立projects --Dynamic-LInk Library工程。

之后添加我们的com_Reliability.h文件到我们的DLL项目中,目录结构如下所示。

头文件中的代码如下所示,com_Reliability.h。

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_Reliability */

#ifndef _Included_com_Reliability
#define _Included_com_Reliability
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_Reliability
 * Method:    shanfei
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_Reliability_shanfei
  (JNIEnv *, jclass, jint);

#ifdef __cplusplus
}
#endif
#endif

实现的Reliability.cpp代码如下所示。

#include<jni.h>
#include "com_Reliability.h"
#include<stdio.h>
#include<jni_md.h>

JNIEXPORT jint JNICALL Java_com_Reliability_shanfei(JNIEnv *, jclass, jint p)
{
	 int j = p*p;
	 return j;

}

     切忌:.cpp中和.h中的方法名一定要相同!!!并且把从java中找到的jni.h 和jni_md.h粘贴到外部依赖文件夹,或者直接放到VC98\include文件夹中。

5、生成dll文件

这样我们ctrl+F7编译,F7在C++项目的debug中生成Reliability.dll文件,这样我们再把这个dll文件放到java编译的.class目录,同时放到MyEclipse与src同级。这样运行java的Reliability.java文件,就看到C++给我们计算的结果了。显示如下所示。

总结:

上述大致就是这个过程,在这个过程中会出现这样或者那样的问题,我也在不断的去尝试错误的所在,尝试改动,最根本的就是计算机报错了,就一定是自己哪个地方有错误,抱着这样的心态,耐心的找答案、尝试、思考,设置断点调试,看到底是哪步出现的错误,最终会解决问题,让你兴奋的看到运行结果。

Java采用JNI调用VC++生成的dll(Java与C++交互)

时间: 2024-08-25 12:00:51

Java采用JNI调用VC++生成的dll(Java与C++交互)的相关文章

Java採用JNI调用VC++生成的dll(Java与C++交互)

应项目需求,须要android调用java,java再调用C++实现android一个图片匹配的功能,我们作为java组须要和C++和Android进行交互.以下是java和C++採用JNI的方式进行接口传參交互,我做的一个demo并执行成功. 什么是JNI? JNI全拼是Java Native Interface,中文意思为Java本地调用.JNI标准是Java平台的一部分.它同意java和其它语言的代码进行交互.JNI開始是为了本地已经编译好的语言,尤其是C和C++而设计的.我们也能够使用J

关于Java通过JNI调用C 动态链接库(DLL)

JNI介绍 用JNI实现Java和C语言的数据传递 JNI原理分析和详细步骤截图说明 jni的JNIEnv指针和jobject指针 JNI实现回调| JNI调用JAVA函数|参数和返回值的格式 Jni接口-深入研究参数的传递(一)

java通过JNI调用c++代码

java通过JNI调用c++代码 1 用java约定接口,生成头文件 创建JniHelloWorld.java public class JniHelloWorld { public JniHelloWorld(){ } public native void sayHello(String name); } 生成头文件供c++使用 javah-jni JniHelloWorld 产生JniHelloWorld.h文件,里面是用c++代码规定了接口形式. 2生成动态链接库文件(http://blo

Java通过JNI调用dll详细过程(转)

源:Java通过JNI调用dll详细过程 最近项目有这样一个需求,在已有的CS软件中添加一个链接,将当前登录用户的用户名加密后放在url地址中,在BS的login方法里通过解密判断,如果为合法用户则无需再次登录直接进入平台,CS软件方提供了一个加密解密的dll文件,我们需要在action中通过该dll解密,那么就涉及到java调用dll的问题. 首先我选择了JNI方式(因为网上说的另两种方式Jawin, Jacob更不会),大体流程如下: 1.写一个java的class,在类里声明所调用的库名称

Java JNI调用c语言的dll测试

最近复习C语言和java语言(10年没用了,温习一下),用JNI调用C语言的dll测试,以前没做过,在网上找了很多,总结如下: 环境:windows 10(64位) + JDK(32位,版本1.7.0_79) + MinGW(32位),注意JDK和MinGW要么都是32位,要么都是64位,不能一个是32位另一个是64位. java和MinGW的环境配置在网上查找. [不用eclipse,用记事本手工编辑 .java和 .c 程序] 1.hello.java代码如下: 2.编译Hello.java

JAVA的JNI调用

由于JNI调用C和调用C++差不多,而且C++中可以混合写C代码,所以这里主要是写关于JNI调用C++的部分. 一般步骤: 先是写普通的Java类,其中包括本地方法调用.  然后编译这个Java类,调用javah命令,生成.h头文件 接着,就是实现头文件中的函数:实现过程中有点比较麻烦,要知道JNI中JAVA和C/C++的类型转换,比如数组类型的转换,基本类型的转换等,最好是看文档,或者网上找相关资料. 源代码链接:http://files.cnblogs.com/GDUT/jni-demo.r

JAVA使用JNI调用C++动态链接库

JAVA使用JNI调用C++动态链接库 使用JNI连接DLL动态链接库,并调用其中的函数 首先 C++中写好相关函数,文件名为test.cpp,使用g++编译为DLL文件,指令如下: g++ -shared -Wl,--kill-at,--output-def,test.def -o test.dll test.cpp #如果cpp中要调用其他dll,需要在命令后面添加相关lib描述 这样就在当路径下同时生成了test.def 和 test.dll 文件 顺便说一下,.lib文件可以通过.def

java 通过jni调用c++实现详解

Java通过JNI调用C++程序 JNI是Java Native Interface的缩写,中文为JAVA本地调用.使用JNI可以很方便的用我们的Java程序调用C/C++程序.很多时候,某些功能用Java无法实现,比如说涉及到底层驱动的一些功能,这时候我们就可以利用JNI来调用C或者C++程序来实现,这就是JNI的强大之处.但是JNI也有它的缺点,使用java与本地已编译的代码交互,通常会丧失平台可移植性. 下面是一个JNI例子,调用C++输出"hello world": 第一步:创

Qt不同版本编译器,调用VC++生成的动态链接库

今天用QT编译生成的共享库自己却怎么都不能调用,查了N久后找到这个帖子,发现搞定了,记录一下 http://qiusuoge.com/12720.html Qt如何调用VC++生成的动态链接库?假设当前有VC++编译器生成的动态库文件testdll.h,testdll.lib和testdll.dll. testdll.h文件源码如下: #ifdef TESTDLL_EXPORTS #define TESTDLL_API __declspec(dllexport) #else #define TE