应项目需求,须要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++交互)的更多相关文章

  1. Java JNI调用c语言的dll测试

    最近复习C语言和java语言(10年没用了,温习一下),用JNI调用C语言的dll测试,以前没做过,在网上找了很多,总结如下: 环境:windows 10(64位) + JDK(32位,版本1.7.0 ...

  2. Qt调用VC++生成的动态链接库

    Qt如何调用VC++生成的动态链接库?假设当前有VC++编译器生成的动态库文件testdll.h,testdll.lib和testdll.dll. testdll.h文件源码如下: #ifdef TE ...

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

    今天用QT编译生成的共享库自己却怎么都不能调用,查了N久后找到这个帖子,发现搞定了,记录一下 http://qiusuoge.com/12720.html Qt如何调用VC++生成的动态链接库?假设当 ...

  4. c++调用matlab生成的Dll动态连接库

    点击打开链接http://download.csdn.net/detail/nuptboyzhb/4228429 c++调用matlab生成的Dll动态连接库 实验平台:   matlab 7.0(R ...

  5. VC生成的DLL给QT的EXE调用时lib路径问题小结

    VC生成的DLL给QT调用,有两种方式,一种是隐式调用调用(使用.lib文件方式): ① 在*.pro工程文件中添加VC生成的lib文件路径时,或者使用一个绝对路径,如: LIBS += " ...

  6. C++调用C#生成的DLL文件的各种问题

    C++调用C#生成的DLL文件: 首先选择建立一个C#的类库,然后再按照需求编写需要的函数 之后,对于C++调用过程需要注意的几点: 1.使用#using <....some.dll>指出 ...

  7. 示例 - 如何在NodeJS中调用SS生成的DLL

    要想在NodeJS中调用SS生成的DLL, 需要借助EdgeJS. EdgeJS: http://tjanczuk.github.io/edge/ 如果你还不知道如何在SS中生成DLL, 请查看: S ...

  8. php通过JavaBridge调用Java类库和不带包的自定义java类成功 但是调用带包的自定义Java类报错,该怎么解决

    php通过JavaBridge调用Java类库和不带包的自定义java类成功 但是调用带包的自定义Java类报错,Class.forName("com.mysql.jdbc.Driver&q ...

  9. 发现个delphi调用vc写的Dll中包括pchar參数报错奇怪现象

    发现个delphi调用vc写的Dll中包括pchar參数奇怪现象 procedure中的第一行语句不能直接调用DLL的函数,否则会执行报错,在之前随意加上条语句就不报错了奇怪! vc的DLL源代码地址 ...

随机推荐

  1. Hadoop Word Count程序

    Hadoop Word Count程序 pom.xml文件: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns ...

  2. 派生类地址比基类地址少4(CDerived对象的起始地址存放的是虚表指针vptr,也就是子类的第一项内容。接下来的是基类的成员变量,接下来再是自身的成员变量)

    大家对虚表并不陌生,都知道每个含有虚函数的类对象都有1个虚指针,但是在现实使用中,却总是因为这而调试半天,才发现原来是虚指针惹的祸.我这几天在调试代码时候也中招了,我的问题是这样的,如下图,CTree ...

  3. Ruby学习笔记(二)——从管道读取数据

    在对文件名修改后,今天又给自己出了新的难题,想从实验结果中提取数据,并将其作为文件夹的名称.其中,比赛的主办方提供的评估算法是用perl写的,因此读取实验结果最为简单的想法自然是使用管道命令,即 ./ ...

  4. IOC与DI区别

    (1)IOC:控制反转,把对象创建交给spring进行配置. (2)DI:依赖注入,向类里面的属性中设置值. (3)关系:依赖注入不能单独存在,需要在IOC的基础之上完成操作.

  5. 剑指offer——01二维数组中的查找(Python3)

    题目:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. ...

  6. 5.文件I/O

    1 C标准函数与系统函数的区别 文件的结构体: 1.1 I/O缓冲区 每一个FILE文件流都有一个缓冲区buffer,默认大小8192Byte. 1.2 效率 文件缓冲区会降低效率.这里提供缓冲区主要 ...

  7. ubuntu下无法将iNode绑定到侧边栏的解决办法

    title: ubuntu下无法将iNode绑定到侧边栏的解决办法 toc: false date: 2018-09-01 17:43:52 categories: methods tags: ubu ...

  8. Activity、Fragment、ViewPage

    1.新建super //super提供统一的FragmentActivity入口.public abstract class SuperFragmentActivity extends Fragmen ...

  9. HD-ACM算法专攻系列(15)——Quoit Design

    问题描述: 源码: 经典问题——最近邻问题,标准解法 #include"iostream" #include"algorithm" #include" ...

  10. C# 正则表达式

    C# 正则表达式 正则表达式 是一种匹配输入文本的模式..Net 框架提供了允许这种匹配的正则表达式引擎.模式由一个或多个字符.运算符和结构组成. 定义正则表达式 下面列出了用于定义正则表达式的各种类 ...