java调用怎么只能加载一次dll库

如题所述

第1个回答  2017-02-15
JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能。解决JAVA对本地操作的一种方法就是JNI。JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式)。通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各接口方法。简单介绍及应用如下:一、JAVA中所需要做的工作在JAVA程序中,首先需要在类中声明所调用的库名称,如下:static{System.loadLibrary(“goodluck”);}在这里,库的扩展名字可以不用写出来,究竟是DLL还是SO,由系统自己判断。还需要对将要调用的方法做本地声明,关键字为native。并且只需要声明,而不需要具体实现。如下:publicnativestaticvoidset(inti);publicnativestaticintget();然后编译该JAVA程序文件,生成CLASS,再用JAVAH命令,JNI就会生成C/C++的头文件。例如程序testdll.java,内容为:publicclasstestdll{static{System.loadLibrary("goodluck");}publicnativestaticintget();publicnativestaticvoidset(inti);publicstaticvoidmain(String[]args){testdlltest=newtestdll();test.set(10);System.out.println(test.get());}}用javactestdll.java编译它,会生成testdll.class。再用javahtestdll,则会在当前目录下生成testdll.h文件,这个文件需要被C/C++程序调用来生成所需的库文件。二、C/C++中所需要做的工作对于已生成的.h头文件,C/C++所需要做的,就是把它的各个方法具体的实现。然后编译连接成库文件即可。再把库文件拷贝到JAVA程序的路径下面,就可以用JAVA调用C/C++所实现的功能了。接上例子。我们先看一下testdll.h文件的内容:#include#ifndef_Included_testdll#define_Included_testdll#ifdef__cplusplusextern"C"{#endifJNIEXPORTjintJNICALLJava_testdll_get(JNIEnv*,jclass);JNIEXPORTvoidJNICALLJava_testdll_set(JNIEnv*,jclass,jint);#ifdef__cplusplus}#endif#endif在具体实现的时候,我们只关心两个函数原型JNIEXPORTjintJNICALLJava_testdll_get(JNIEnv*,jclass);和JNIEXPORTvoidJNICALLJava_testdll_set(JNIEnv*,jclass,jint);这里JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的。而jint是以JNI为中介使JAVA的int类型与本地的int沟通的一种类型,我们可以视而不见,就当做int使用。函数的名称是JAVA_再加上java程序的package路径再加函数名组成的。参数中,我们也只需要关心在JAVA程序中存在的参数,至于JNIEnv*和jclass我们一般没有必要去碰它。好,下面我们用testdll.cpp文件具体实现这两个函数:#include"testdll.h"inti=0;JNIEXPORTjintJNICALLJava_testdll_get(JNIEnv*,jclass){returni;}JNIEXPORTvoidJNICALLJava_testdll_set(JNIEnv*,jclass,jintj){i=j;}编译连接成库文件,本例是在WINDOWS下做的,生成的是DLL文件。并且名称要与JAVA中需要调用的一致,这里就是goodluck.dll。把goodluck.dll拷贝到testdll.class的目录下,javatestdll运行它,就可以观察到结果了。

Java调用DLL文件,第一次时正常可以使用,第二次的
10将调用的Java类文件打包成jar文件 20将打包好的jar文件Tomact的lib文件夹下,这样整个项目中调用的dll文件只被调用一次Java调用DLL文件,第一次时正常可以使用,第二次的

java调用dll
采用JNA库进行调用时,首先需要在项目中引入相应的jar包,这个版本是com.sun.jna的jna库,版本为3.0.9。一个关键点是,DLL\/SO库在不同操作系统下的加载方式有所不同。Linux\/Unix系统通常使用SO文件,而Windows系统则使用DLL。Windows系统对DLL文件的加载路径有所限制,通常在JDK的安装目录下的jre\/bin...

java调用dll出错?
当使用System.load时,需要输入文件的全路径,例如:System.load(“\/tmp\/test.so”);当使用System.loadlibrary时是在系统的library 的目录中需找复合条件的库文件,可以使用-Djava.library.path=[path]参数,来指定Java程序加载库文件的路径,或者将库文件(*.so,*.dll)复制到include的默认路径,Linux...

用Java调用dll里面的函数,成功了是什么效果?为什么我的只是后台打印出来...
比如dll文件是调用读卡器的接口,java调用dll中的ReadID()方法就会把卡中的卡号获得,java调用sound()方法就会让读卡器发出响声

如何解决java调dll报Unable to load library的错误
在window系统下,需要将需要加载的库文件(.dll)放在JDK安装目录下的include目录下,在linux系统下一般是放到\/usr\/lib目录下。也可以使用-Djava.library.path=[path]参数,来指定Java程序加载库文件的路径。3、在window中,最好使用Windows的C\/C++编译器生成dll文件,否则调用会有一些问题。

请问JAVA可以调用DLL或者EXE吗?C#可以调用JAR包吗?为什么?
如果直接从java调用DLL或exe肯定是不行的。因为java程序生产的字节码,且必须运行在java虚拟机中,java程序根本不认识二进制的或IL格式的dll或exe;反正,c#程序的格式是IL,无法识别字节码格式的java包,因此也无法直接调用。

dll动态调用和静态调用有什么区别
1、静态调用时,如果exe所在的文件夹没有dll文件及其lib文件,则运行exe会报错。及exe根本就运行不起来 ,系统提示没有找到dll文件等信息。错误信息是不可控的。 2、动态调用只有再调用dll文件时,如果没有,才会报错,并且此错误时可控的。 如果dll没有对应的.lib文件,那么就只能使用动态加载的方式了。 本回答由电脑网...

如何把自己写的exe\/dll给别人调用
我试着做了一下,果然就可以了!因为Java虚拟机不会主动去搜索系统中的path,所以即使把动态链接库加到System32文件夹中也不济于事。此步具体操作如下:如何把自己写的exe\/dll给别人调用 上面说了这个是由于Java虚拟机不去主动找系统path才会出现的问题,如果是用c++调用的话则简单多了。自己写好exe...

求一段java调用DLL的程序,该程序可以让JVM直接崩溃,或者一段JAVA代码让...
让jvm崩溃,还有这样子的需求?那你就无限的new对像,存到内存中不释放,代码嘛:while(true){list.add(new Object());}

...需要不要在使用这个dll的程序上面再去安装java的运行环境?
朋友你问的问题有点太搞笑了吧,java编写的文件编译后是.class的文件,只有使用C\/C++,VB这些东西才能编写出DLL文件。java文件是需要JDK才能运行的,DLL文件叫动态链接库,是不能直接运行的。

相似回答