精华内容
下载资源
问答
  • Java通过JNI调用DLL动态库,亲测试编写
  • java通过JNI调用DLL文件

    千次阅读 2019-04-13 19:44:26
    JNI简介: JNIJava Native Interface的缩写,它提供了若干的API实现了...JNI 允许Java程序调用其他语言编写的程序或者代码库, 比如C/C++。Java 在内存管理和性能上有一定的局限,通过JNI我们就可以利用Native程...

    JNI简介:

    JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。允许Java代码和其他语言写的代码进行交互。JNI是JDK提供的一个native编程接口。JNI 允许Java程序调用其他语言编写的程序或者代码库, 比如C/C++。Java 在内存管理和性能上有一定的局限,通过JNI我们就可以利用Native程序来克服这些限制

    具体示例:

    写一个java调用c的加减乘除的dll文件

    1、先在编辑器中写好java代码如:

    package com.li.dll;
    
    
    /**
     * @author MR.li
     *	java通过JNI调用DLL文件
     */	
    public class JToDll {
    	//加载DLL库的方法 System.loadLibrary()
            //不用指定后缀".dll"
    	static {
    		System.loadLibrary("Math");
    	}
    	//DLL库中对应的方法
    	public native int dll_add(int a,int b); //加法
    	public native int dll_sub(int a,int b); //减法
    	public native int dll_mul(int a,int b); //乘法
    	public native int dll_div(int a,int b); //除法
    	
    	public static void main(String[] args) {
    		
    		JToDll dll = new JToDll();
    		int add = dll.dll_add(2, 3);
    		int sub = dll.dll_sub(8, 5);
    		int mul = dll.dll_mul(5, 6);
    		int div = dll.dll_div(20, 4);
    		
    		System.out.println("add="+add+";sub="+sub+";mul="+mul+";div="+div);
    	}
    	/*
    	 * native 关键字告诉编译器(其实是JVM)调用的是该方法在外部定义,这里指的是C。
    	 */
    }
    

    2、对你写好的这个java进行编译成class文件,在eclipse的话可以直接拿到class文件,在这里我用cmd命令进行编译

    3、使用javah命令生成c所需要的头文件

    在cmd中进入到你项目所在的bin目录然后执行cmd命令,

    注意:没有.class  而且 如果有包名的话 记得要把包名也写上

    执行cmd命令后会在你的bin目录下生成.h的头文件

    4、使用vs2017创建dll动态链接库

    点击右上角文件选择新建项目

     之后会有一个弹出框,选择右边的windows桌面和左边的动态链接库,下边的名称是这个dll动态链接库项目的名称、位置是这个项目的存放位置

    最后点击确定就创建项目了如:

    5、在C/C++项目中导入头文件

    此时出了导入刚刚生成的.h文件,还需要导入java的头文件 jni.h 和jni_md.h

    jni.h 以及jni_md.h的路径在 java的安装位置下的include文件夹内 以及win32下

     导入顺序为先导入刚创建的项目,其次在导入编辑器中如:

     

    如果跳过项目文件夹导入直接导入到编辑器中是会报错的,原因是在项目中找不到这个文件

    6、编写程序并打包DLL库

    // Math.cpp : 定义 DLL 应用程序的导出函数。
    //
    
    #include "stdafx.h"
    
    #include "jni.h"
    #include "jni_md.h"
    #include "com_li_dll_JToDll.h"
    
    
    
    JNIEXPORT jint JNICALL Java_com_li_dll_JToDll_dll_1add(JNIEnv *, jobject, jint a, jint b) {
    	return a + b;
    }
    JNIEXPORT jint JNICALL Java_com_li_dll_JToDll_dll_1sub(JNIEnv *, jobject, jint a, jint b) {
    	return a - b;
    }
    JNIEXPORT jint JNICALL Java_com_li_dll_JToDll_dll_1mul(JNIEnv *, jobject, jint a, jint b) {
    	return a * b;
    }
    JNIEXPORT jint JNICALL Java_com_li_dll_JToDll_dll_1div(JNIEnv *, jobject, jint a, jint b) {
    	return a / b;
    }

    其中的函数直接从你生成的头文件中赋值粘贴拿过来把函数的内容自己补上就可以

    注意:编译的时候有x86和x64的选择,区别是x84是32位的x64是64位的

    编译时可能还报找不到jni.h的错误,可以将#include <jni.h>改为#include "jni.h",因为前者是引用系统头文件的写法

    点击顶部的生成选择生成解决方案进行编译:

    在底部会有编译的信息其中就有生成的dll文件路径:(这里我选择是是64位因为我的jdk是64的——根据自己需要来选择生成对应的文件)

    打开文件看一下

    7、将生成的dll文件放入System32下(64位放入SysWOW64下)或者放入项目文件中(访问System32下的可以跳过这一步)

     

    我在这里直接放入项目中,新建lib文件夹将Math.dll文件放入最后右键项目build Path ->Configure Build Path->Libraries->Native library location双击编辑路径选择为项目下的lib文件夹

    8、加载dll文件运行项目

    注意加载时不用指定后缀".dll"

    运行结果:

     

    java与JNI数据类型对应表

    JNA调用dll文件

     

    展开全文
  • JAVA如何调用dll:用JNI调用C或C++动态联接库原来如此简单.doc
  • Java JNI调用DLL方法

    2011-02-24 15:47:59
    JAVA中如何通过JNI调用VC动态库,以及在如何在VC中调试
  • windows java jni调用dll

    2018-04-08 18:58:02
    编写带有native声明的方法的java类,生成.java文件使用javac命令编译所编写的java类,生成.class文件使用javah -jni java类名生成扩展名为h的头文件,也即生成.h文件使用C/C++(或者其他编程想语言)实现本地方法,...


      1. 编写带有native声明的方法的java类,生成.java文件
      2. 使用javac命令编译所编写的java类,生成.class文件
      3. 使用javah -jni java类名生成扩展名为h的头文件,也即生成.h文件
      4. 使用C/C++(或者其他编程想语言)实现本地方法,创建.h文件的实现,也就是创建.cpp文件实现.h文件中的方法
      5. 将C/C++编写的文件生成动态连接库,生成dll文件

    public class HelloJni {
    native void hello();  
        
        static {  
            System.loadLibrary("HelloJni");  
        }  
          
        public static void main(String args[]) {  
            HelloJni helloJni = new HelloJni();  
            helloJni.hello();  
        }  

    }


    cmd进入到HelloJni.java文件夹,然后执行javah -jni java HelloJni命令 生成HelloJni .h头文件。

    #ifndef _Included_HelloJni
    #define _Included_HelloJni
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     HelloJni
     * Method:    hello
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_HelloJni_hello
      (JNIEnv *, jobject);


    #ifdef __cplusplus
    }
    #endif
    #endif

    然后在vs2017建立一个空项目,导入头文件,同时把这个文件复制到项目所在文件夹。

    执行编译,这时可能会报错,提示jni.h找不到,需要将jni.h所在的文件加入到项目的包含目录中。可以在项目中点右键->属性,然后参照下面的图添加。




    然后添加一个主程序

    #include "HelloJni.h"  
    #include <stdio.h>  
    #include <jni.h>  
    /*
    * Class:     HelloJni
    * Method:    hello
    * Signature: ()V
    */
    JNIEXPORT void JNICALL Java_HelloJni_hello
    (JNIEnv * env, jobject)
    {
    printf("Hello Jni!\n");
    return;

    }


    改成dll然后生成解决方案。

    把这个文件copy到C:\Windows\System32 和java项目下就可以了。只是会报Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Windows\System32\HelloJni.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform 应该是这只能生成32位的dll我们64位的平台无法调用。不过大概过程就是这样了。

    展开全文
  • Java通过JNI调用VC的DLL总结

    千次阅读 2018-12-14 16:57:41
    Java下有时一些需要效率的操作要用C++来完成,调用C/C++的库一般有两种方式,JNI和JNA。自己学习JNI时也遇到不少坑,这里总结一下JNI的使用过程。 建立Java Project项目: 建立Java类文件,填入包名和类名: ...

    Java下有时一些需要效率的操作要用C++来完成,调用C/C++的库一般有两种方式,JNI和JNA。自己学习JNI时也遇到不少坑,这里总结一下JNI的使用过程。
    建立Java Project项目:
    Java Project项目
    建立Java类文件,填入包名和类名:
    填入包名和类名
    写入如下代码:
    CdesDll 代码
    如果Eclipse设置自动编译的话,现在在项目bin目录下应该生成了CdesDll.class文件,接下来使用javah命令生成C++需要的.h文件,也就是给C++生成接口。
    原来自己写头文件,但JNI要求的函数命名规则是比较严格的,写错一点就调用不成功,期间也走了不少弯路。现在Java有javah命令为我们自动生成头文件了,既然有现成工具,最好就别自己写了。
    在使用javah命令前需要注意的是javah查找的是CLASSPATH设定的路径,如果这个路径下没有要处理的java类文件就会报错。如果CLASSPATH环境变量已经设置为.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;:
    CLASSPATH环境变量
    这里的环境变量不区分大小写,注意到第一个路径为“.”即当前路径,那么使用javah命令时要进入java类文件的当前路径,由于这里的CdesDll类是带有包名的(com.des.jni),所以要进入com文件夹所在路径(E:\workspace\CDESDLL\bin):
    包路径
    其实.java和.class文件都可以识别的,因此换为com\des\jni\CdesDll.java所在的src路径一样:
    源码路径
    使用命令行进入项目的bin目录,输入命令:

    javah -jni com.des.jni.CdesDll
    

    如果没设置CLASSPATH环境变量,需要指定-classpath参数,同样使用命令行进入项目的bin目录,输入命令:

    javah -classpath . -jni com.des.jni.CdesDll  (注意“.”两边各有一个空格)
    

    说明
    -classpath <路径>用于装入类的路径
    -jni 生成JNI样式的头文件(默认)
    我这里使用的是JDK1.8,结果就报错了:
    JDK1.8报错
    看来JDK1.8不支持生成JNI的.h文件了,换成JDK1.7试试,输入如下命令:

    "C:\Program Files\Java\jdk1.7.0_51\bin\javah" -jni com.des.jni.CdesDll
    

    JDK1.7命令
    由于懒得改环境变量,这里直接使用JDK1.7的javah命令所在的全路径,为什么路径加上引号呢,因为这个路径是有空格的,直接使用会因为把空格前断开处理而报错,这里使用一个小技巧。这下在src目录下生成了想要的com_des_jni_CdesDll.h文件:
    头文件生成
    com_des_jni_CdesDll.h文件内容如下:
    头文件内容
    这里为什么用src路径下的原java文件生成呢,虽然上面说了两个文件都可以使用,但因为刚才bin目录下的.class文件是用JDK1.8编译的,如果使用的话会出现编译器版本更新的警告,虽然不影响.h文件生成,为稳妥起见,还是用原java文件吧。

    打开VS2010,创建一个Win32项目:
    Win32项目
    应用程序的类型选择DLL,这里不用勾选“导出符号”,com_des_jni_CdesDll.h文件已经为我们写好了,之后加进项目来就可以了:
    DLL设置
    生成项目后,不仅要把com_des_jni_CdesDll.h文件添加进来,还得把JDK1.7的include目录下jni.h文件:
    jni.h文件
    和win32目录下的jni_md.h文件添加进项目:
    项目结构
    CdesDll.cpp代码中加入头文件:

    #include "jni.h"
    #include "com_des_jni_CdesDll.h"
    

    由于jni_md.h文件在jni.h文件中已经包含,不需要单独添加了:
    jni_md.h文件
    编译时生成的com_des_jni_CdesDll.h文件可能报错:
    头文件报错
    这句改成#include "jni.h"就好了。然后写与Java对应的那个testDll的实现函数,CdesDll.cpp添加如下代码:

    JNIEXPORT jint JNICALL Java_com_des_jni_CdesDll_testDll(JNIEnv *, jclass, jint value)
    {
    	int res = value * 4;
    	return res;
    }
    

    写了一个简单的测试函数,只是把输入的值扩大四倍,然后返回。写好了编译试一下,这里需要编译Release版本,而且与JDK1.7的位数要一致,这里是64位的,所以更改项目设置,新建一个x64平台:
    x64平台
    生成的dll要放在Eclipse工程的根目录下,否则加载库会失败:
    工程根目录
    我测试时很不幸,调用时出现如下错误:

    Exception in thread "main" java.lang.UnsatisfiedLinkError: com.des.jni.CdesDll.testDll(I)I
    	at com.des.jni.CdesDll.testDll(Native Method)
    

    一般出现这种错误是因为函数名不符合格式要求造成的,Java找不到对应函数,再次核对下函数名,是照着com_des_jni_CdesDll.h文件写的啊,这个头文件是由javah命令生成的,应该不会错。
    使用CFF_Explorer工具查看一下生成的CdesDll.dll文件,看看函数是否正确导出了:
    分析库函数
    C++编译的函数名字会有些改变的,难道这样Java就不认了吗?改为C编译器试试:

    #ifdef __cplusplus
    extern "C" {
    #endif
    JNIEXPORT jint JNICALL Java_com_des_jni_CdesDll_testDll(JNIEnv *, jclass, jint value)
    {
    	int res = value * 4;
    	return res;
    }
    #ifdef __cplusplus
    }
    #endif
    

    再编译这下dll也报错了:

    CdesDll.cpp(12): error C2733: 不允许重载函数“Java_com_des_jni_CdesDll_testDll”的第二个 C 链接
    1> CdesDll.cpp(11) : 参见“Java_com_des_jni_CdesDll_testDll”的声明
    

    函数重复定义了?可是我就定义了一个啊。再仔细检查头文件和源文件:
    头文件定义
    源文件实现
    发现二者的区别了吧,原来函数参数不同啊,静态方法才用jclass类型了,赶紧改为jobject吧。这次编译没错了,Java调用也正常了。那为什么刚才用C++编译的时候就不报错呢,熟悉C++的朋友应该都知道,C++有个特性叫重载(允许函数名相同而只是参数不同),当然这在C里面是不允许的。所以C++编译没报错,但是头文件的那个函数却没有对应的实现代码,Java调用它不报错就怪了。

    上面写的测试函数只是简单传参int类型,实际项目中很可能传输其他更复杂类型的参数,只要找到JNI里面的对应类型即可。比如要向dll传输char数组,Java里可别直接写char[],因为Java的char是为Unicode编码考虑的,也就是说是两个字节,而非C/C++里的char,Java里要用byte[]。Javah命令会把byte[]转为jbyteArray,C或C++里要想转为char*得用到下面的转换:

    /* jbyteArray dataArr 传来的参数 */
    jbyte *dataBytes = env->GetByteArrayElements(dataArr, 0);
    int iDataSize = env->GetArrayLength(dataArr);
    
    unsigned char *cData= new BYTE[iDataSize+1];
    memset(cData, 0, iDataSize+1);
    memcpy(cData, dataBytes, iDataSize);
    

    那要是想把char*转会jbyteArray返回去该怎么办呢?

    /* 继续上面代码 */
    jbyte* jbp = (jbyte*)cData;
    jbyteArray resArr = env->NewByteArray(iDataSize);
    env->SetByteArrayRegion(resArr, 0, iDataSize, jbp);
    
    delete []cData;
    return resArr;
    

    详细的代码我已经上传CSDN了,如果还有不明白的地方请下载进行比对。资源下载地址:
    https://download.csdn.net/download/xinxin_2011/10851026

    展开全文
  • 这两天要弄个JAVA调用DLL,研究了一下有点绕, java部分要生成.h头文件,所以弄了个例子在这分享下 JAVA调用DLL完整步骤 步骤里包括java部分代码及vc写的DLL代码
  • 完整的实现java跨平台调用C程序源码,包含JAVA源码和C源码以及编译后的demo dll。将dll放到jdk bin目录下,java 项目可以直接运行。若要修改dll可以,修改C源码后重新编译生成dll。该demo处理了多线程调用c,全局...
  • java程序调用c++的dll文件 ,idea 配置

    1.java程序调用c++的dll文件 ,idea 配置

    -Djava.library.path=D:\VScodeWebapp\testJNI1\x64\Release

    2.调用过程注意点

    dll打包过程中打包版本是64位匹配本机电脑,不然运行不成功

    展开全文
  • 问题描述: 在开发项目过程中,需要处理算法分析出来二进制流数据,并对数据解析处理转发。我们上层应用平台是使用java开发的...那现在上层应用面临的问题:访问java外部功能接口实现方式(即调用dll)怎么选择及实现?
  • Java调用C#的dll是通过C++作为桥梁,JNI—>C++的dll(clr方式运行)—>C#的dll   以下为本次测试的配置环境:  系统:win7 64位  Java开发环境(均为64位):JDK1.8、eclipse  C++开发环境:VS2015  整个...
  • 本资源包括JAVA工程,C++工程,C#dll测试工程
  • JAVA如何调用dll:用JNI调用C或C++动态联接库原来如此简单
  • [JAVA]使用JNI技术实现JAVA程序调用dll、[JAVA]使用JNI技术实现JAVA程序调用dll
  • Java通过JNI 调用动态链接库DLL

    千次阅读 2017-02-03 17:26:54
    JNI(Java Native Interface)Java本地接口,主要作用是实现java代码与C、C++编写的代码交互。...如下:例:java调用demo.dll文件中的 hello()方法。1、java1)装载dll文件 有两种方式System.load();和System.load
  • 下面是我写的调用DLL的部分代码:class GetValue{ public native String getCalcValue(String strSoftware,int iType,String strIndata); static { System.out.println("静态代码快"); ...
  • 最近有个项目,需要调用别人c++ 封装的dll动态库文件,通过javaJNI进行调用实现。在运行程序加载dll时报错如下: java.lang.UnsatisfiedLinkError: D:\workspace\myzauto\lib\getcpu.dll: Can't find dependent ...
  • Java通过JNI调用C++接口,Demo文档描述(里面有代码),里面有Windows下调用版和linux下调用版,经本人亲自测试,可用。
  • JNI 调用 DLL

    千次阅读 2019-06-19 13:30:31
    JNIJava Native Interface的简称,该功能主要是用于Java调用C的动态库,实现某些功能,其使用过程主要分为以下几步: 新建一个Java类,该类中定义自己需要的 C 端的native方法; 根据该类编译生成的.class...
  • java dll文件调用的几种方式,是intellij 项目,用eclipse的话要自己导一下,相信大家都会
  • jni调用dll扩展程序直接配置-Djava.library.path来指定dll所在目录即可以加载到dll,但是如果dll要依赖其它dll的时候会提示 Can't find dependent librarie即找不到dll的依赖库,这种情况可以将需要依赖的dll放到...
  • Java通过JNI调用C++的DLL文件

    千次阅读 2018-09-04 18:05:17
    1、在eclipse中创建一个Java工程 2、创建一个测试类,如下图MyClass.java 3、cmd打开命令提示符窗口,进入到src目录下,javac命令生成class文件; 4、然后后用javah命令生成 .h头文件,如下图: 5、使用vs...
  • 项目中需要对接其他系统,需要通过一个jar包调用对方系统接口,但是这个jar包通过jni调用了.dll文件,一开始在ide中运行提示在“C:\Program Files\Java\jdk1.8.0_271\jre”目录下无法找到.dll文件,好吧,那就把对方...
  • 以前基于JNI使用C++的项目,都是安卓项目,jni和C++源码部分通过androidstudio提供的cmakelist直接编译使用。...1.使用VS生成dll的过程中,java和c++的桥接代码部分,也就是根据javah生成的文件,...
  • Java JNI调用dll中的C代码
  • Java JNI 调用C/C++ 本地库(dll/so) 阅读目录 一. 什么是JNI 二. 编写带有native声明的方法的java类 三. 使用javac命令编译所有的java类 四. 使用javah命令生成.h文件(javah 包名.类名) 五. 使用C/C++实现本地...
  • NULL 博文链接:https://leesonhomme.iteye.com/blog/549034
  • jni 调用dll jvm崩溃的可能

    千次阅读 2018-05-28 11:02:21
    dll用release输出2 如果从java中传入对象到native,对象中的部分非基本数据属性不能为空3 byte数组拷贝返回java,不能用memcpy,要用SetByteArrayRegion,unsigned char* 可以强制转换为(jbyte*)4 释放指针的...
  • java利用JNI 调用C++(dll)函数完整代码示例

    千次阅读 热门讨论 2021-01-11 16:25:33
    JNI(Java Native Interface)意为JAVA本地调用,它允许Java代码和其他语言写的代码进行交互,简单的说,一种在Java虚拟机控制下执行代码的标准机制。 第一步:创建好一个类 创建一个Java类,例如JNITest.java,具体...
  • 完整的展示了Java调用C++ API/dll示例程序. 说明如下: 1. mrSocketAPICInt是准备被java调用的API 2. mrSocketAPIJavaInt是java调用C++ api的中间层 3. mrSocketAPIJavaIntDemo是java程序,展示与C++ api如何对接。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,242
精华内容 4,896
关键字:

javajni调用dll

java 订阅