应项目需求,须要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. [Tailwind] Abstract Utility Classes to BEM Components in Tailwind

    When creating UIs with utility classes, a lot of repetition can occur within the HTML markup. In thi ...

  2. HDU 1171 Big Event in HDU(多重背包)

    Big Event in HDU Problem Description Nowadays, we all know that Computer College is the biggest depa ...

  3. 开发效率必备之Mac双屏显示

    自从2015年9月苹果公布EI Captain,带来了一个新的功能,叫做分屏,也就是在一块屏幕上分成左右两部分,能够分别进行操作,互不影响. 例如以下图所看到的: watermark/2/text/a ...

  4. JavaSE 最easy出错的几个简单的问题

    案例1. package cn.itcast.oop; public class ThisDemo { public static void main(String[] args) { Student ...

  5. Python·Jupyter Notebook各种使用方法记录

    标签(空格分隔): Python 一 Jupyter NoteBook的安装 1 新版本Anaconda自带Jupyter 2 老版本Anacodna需自己安装Jupyter 二 更改Jupyter ...

  6. html 中表单元素input type="hidden"的作用

    转自:https://blog.csdn.net/xiaobing_122613/article/details/54946559 (隐藏只是在网页页面上面不显示输入框,但是虽然隐藏了,还是具有for ...

  7. 利用CSS3中的clac()实现按照屏幕分辨率自适应宽度

    1.简介 calc()看其外表像个函数.平时在制作页面的时候,总会碰到有的元素是100%的宽度(例如body元素).如果元素宽度为100%时,其自身不带其他盒模型属性设置还好,要是有别的,那将导致盒子 ...

  8. PySide2运行出错问题解决

    PySide2是QT官方出的Python的QT封装, 不过默认安装运行时候会有一些小问题, 可能是系统里已经安装过其他版本QT的原因, 会报错如下: PySide2 qt.qpa.plugin: Co ...

  9. Java语言的优点

    1)Java为纯面向对象的语言. <Thinking in Java>提到Java语言是一种“Everything is object”的语言,它能够直接反应现实生活中的对象, 例如火车, ...

  10. 关于swift构造方法

    switf 中如果遇到这样的错,,,大概错误就是,"必须要调用父类的构造方法",,可是呢,,调用了super.init()  不就是调用了构造方法了吗? 结果上去一查,,结果一名外 ...