• 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:javain....,那我的JAVA_HOME为:C:java 。path文件夹:引用JAVA_HOME而且加上in ,为 %JAVA_HOME%in

    classpath为: .;%JAVA_HOME%libdt.jar;%JAVA_HOME%lib ools.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粘贴到外部依赖目录。或者直接放到VC98include目录中。


         5、生成dll文件

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



         总结:

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





  • 相关阅读:
    关于数组的练习题:
    函数(手写)
    常用函数和方法集
    用户输入年,月,日,计算该日是该年的第几天?需要考虑2月份的问题
    [备用] 你会在C#的类库中添加web service引用吗?
    [备用]权限设计方案、如何使用session、MVC如何使用模板、DropdownList、怎么添加Bootstrape框架、使用ASP.NET MVC 4 Bootstrap Layout Template(VS2012)
    [转:Pro ASP.NET MVC 5中的例子]使用MVC4,Ninject,EF,Moq,构建一个真实的应用电子商务SportsStore
    莫名其妙
    [备用] VS中生成报表
    [备用] 百度地图兴趣点抓取
  • 原文地址:https://www.cnblogs.com/jhcelue/p/7029193.html
Copyright © 2020-2023  润新知