导航:首页 > 编程语言 > javajni编程

javajni编程

发布时间:2023-07-16 09:51:37

‘壹’ java 调用动态链接库(jni方式调用dll文件)

jni 是由Java调用C/C++的动态链接库 (DLL)。
所以把.class-->.h-->dll ,想法是不正确的,
同时也违背了Jni的初衷。
Dll是由C/C++生成的。

以前的一个项目用到了Java调用C/C++的DLL,所以对这个还算熟悉。
那个dLL是由C++程序员写的,在Microsoft Visual C++ 6.0编辑器中可以生成。然后由Java程序员用JNI来调用DLL里面实现的功能(方法)。

‘贰’ 如何用JNI技术提高Java的性能详解

阻碍Java取得广泛使用的一个首要因素是Java程序的运行效率。Java是介于解释型和编译型之间的一种语言,同样的程序,假如用编译型语言C来实现,其运行速度通常要比Java快一倍以上。Java具有平台无关性,这使人们在开发企业级使用的时刻总是把它作为首要候选方案之一,但是性能方面的因素又大大削弱了它的竞争力。为此,提高Java的性能就显得十分主要。 疑问的提出 Sun公司及Java的支撑者们为提高Java的运行速度已经做出了许多全力,其中大多数集中在程序设计的要领和模式挑选方面。由于算法和设计模式的优化是通用的,对Java有效的优化算法和设计模式,对其他编译语言也基本同样适用,因此无法从根本上改动 Java程序与编译型语言在执行效率方面的差别。 JIT(Just In Time,及时编译)技能是个比较好的思想。它的基本原理是:最先议决 Java编译器把Java源代码编译成平台无关的二进制字节码。然后在Java程序真实执行之前,系统议决 JIT编译器把Java的字节码编译为本地化机器码。结尾,系统执行本地化机器码,节省了对字节码实行解释的时间。这样做的优点是大大提高了Java程序的性能,缩短了加载程序的时间;同时,由于编译的结果并不在程序运行间保存,因此也节约了存储空间。缺点是由于JIT编译器对所有的代码都想优化,因此同样也占用了许多时间。 动态优化技能是提高Java性能的另一个尝试。该技能试图议决把Java源程序直接编译成机器码,以充分使用 Java动态编译和静态编译技能来提高Java的性能。该要领把输入的Java源码或字节码转换为经历高度优化的可执行代码和动态库 (Windows中的. dll文件或Unix中的. so文件)。该技能能大大提高程序的性能,但却破坏了Java的可移植性。 JNI技能 实际上,有一种通常为咱们忽视的技能能够在很大程度上处理这个难题,那就是JNI(Java Native Interface, Java本地化要领 )。主张采用纯Java的人们通常反对本地化代码的运用,他们认为在Java程序执行的流程中调用C/C++程序会影响程序的可移植性和安全性。还有一些人认为JNI只是对过去混合编程技能的基本扩展,本来际目标是为了充分使用大量原有的C程序库。 本来,咱们不必拘泥于严格的平台独立性限定,因为采用JNI技能只是针对一些严重影响Java性能的代码段,该部分可能只占源程序的极少部分,所以几乎能够不思虑该部分代码在主流平台之间移植的工作量。同时,也不必过分担心类型匹配疑问,咱们完全能够控制代码不出现这种不正确。此外,也不必担心安全控制疑问,因为Java安全模型已扩展为准许非系统类加载和调用本地点法。根据Java规范,从JDK 1. 2开始,FindClass将设法找到与当前的本地点法关联的类加载器。假如平台有关代码属于一个系统类,则无需涉及任何类加载器; 否则,将调用适当的类加载器来加载和链接已命名的类。换句话说,假如在Java程序中直接调用C/C++语言产生的机器码,该部分代码的安全性就由Java虚拟机控制。

‘叁’ C调用java时使用JNI的问题!急。。。。。

M,是其中的一个组成部分,更详细的看下面:

----------------------------------
操作系统装入jvm是通过jdk中java.exe来完成,通过下面4步来完成jvm环境.
1.创建jvm装载环境和配置
2.装载jvm.dll
3.初始化jvm.dll并挂界到JNIENV(JNI调用接口)实例
4.调用JNIEnv实例装载并处理class类。

在我们运行和调试java程序的时候,经常会提到一个jvm的概念.jvm是java程序运行的环境,但是他同时一个操作系统的一个应用程序一个进程,因此他也有他自己的运行的生命周期,也有自己的代码和数据空间.
首先来说一下jdk这个东西,不管你是初学者还是高手,是j2ee程序员还是j2se程序员,jdk总是在帮我们做一些事情.我们在了解java之前首先大师们会给我们提供说jdk这个东西.它在java整个体系中充当着什么角色呢?我很惊叹sun大师们设计天才,能把一个如此完整的体系结构化的如此完美.jdk在这个体系中充当一个生产加工中心,产生所有的数据输出,是所有指令和战略的执行中心.本身它提供了java的完整方案,可以开发目前java能支持的所有应用和系统程序.这里说一个问题,大家会问,那为什么还有j2me,j2ee这些东西,这两个东西目的很简单,分别用来简化各自领域内的开发和构建过程.jdk除了jvm之外,还有一些核心的API,集成API,用户工具,开发技术,开发工具和API等组成
好了,废话说了那么多,来点于主题相关的东西吧.jvm在整个jdk中处于最底层,负责于操作系统的交互,用来屏蔽操作系统环境,提供一个完整的java运行环境,因此也就虚拟计算机. 操作系统装入jvm是通过jdk中java.exe来完成,通过下面4步来完成jvm环境.
1.创建jvm装载环境和配置
2.装载jvm.dll
3.初始化jvm.dll并挂界到JNIENV(JNI调用接口)实例
4.调用JNIEnv实例装载并处理class类。
一.jvm装入环境,jvm提供的方式是操作系统的动态连接文件.既然是文件那就一个装入路径的问题,java是怎么找这个路径的呢?当你在调用java test的时候,操作系统会在path下在你的java.exe程序,java.exe就通过下面一个过程来确定jvm的路径和相关的参数配置了.下面基于windows的实现的分析.
首先查找jre路径,java是通过GetApplicationHome api来获得当前的java.exe绝对路径,c:\j2sdk1.4.2_09\bin\java.exe,那么它会截取到绝对路径c:\j2sdk1.4.2_09\,判断c:\j2sdk1.4.2_09\bin\java.dll文件是否存在,如果存在就把c:\j2sdk1.4.2_09\作为jre路径,如果不存在则判断c:\j2sdk1.4.2_09\jre\bin\java.dll是否存在,如果存在这c:\j2sdk1.4.2_09\jre作为jre路径.如果不存在调用GetPublicJREHome查HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment\“当前JRE版本号”\JavaHome的路径为jre路径。
然后装载jvm.cfg文件JRE路径+\lib+\ARCH(CPU构架)+\jvm.cfgARCH(CPU构架)的判断是通过java_md.c中GetArch函数判断的,该函数中windows平台只有两种情况:WIN64的‘ia64’,其他情况都为‘i386’。以我的为例:C:\j2sdk1.4.2_09\jre\lib\i386\jvm.cfg.主要的内容如下:
-client KNOWN
-server KNOWN
-hotspot ALIASED_TO -client
-classic WARN
-native ERROR
-green ERROR
在我们的jdk目录中jre\bin\server和jre\bin\client都有jvm.dll文件存在,而java正是通过jvm.cfg配置文件来管理这些不同版本的jvm.dll的.通过文件我们可以定义目前jdk中支持那些jvm,前面部分(client)是jvm名称,后面是参数,KNOWN表示jvm存在,ALIASED_TO表示给别的jvm取一个别名,WARN表示不存在时找一个jvm替代,ERROR表示不存在抛出异常.在运行java XXX是,java.exe会通过CheckJvmType来检查当前的jvm类型,java可以通过两种参数的方式来指定具体的jvm类型,一种按照jvm.cfg文件中的jvm名称指定,第二种方法是直接指定,它们执行的方法分别是“java -J”、“java -XXaltjvm=”或“java -J-XXaltjvm=”。如果是第一种参数传递方式,CheckJvmType函数会取参数‘-J’后面的jvm名称,然后从已知的jvm配置参数中查找如果找到同名的则去掉该jvm名称前的‘-’直接返回该值;而第二种方法,会直接返回“-XXaltjvm=”或“-J-XXaltjvm=”后面的jvm类型名称;如果在运行java时未指定上面两种方法中的任一一种参数,CheckJvmType会取配置文件中第一个配置中的jvm名称,去掉名称前面的‘-’返回该值。CheckJvmType函数的这个返回值会在下面的函数中汇同jre路径组合成jvm.dll的绝对路径。如果没有指定这会使用jvm.cfg中第一个定义的jvm.可以通过set _JAVA_LAUNCHER_DEBUG=1在控制台上测试.
最后获得jvm.dll的路径,JRE路径+\bin+\jvm类型字符串+\jvm.dll就是jvm的文件路径了,但是如果在调用java程序时用-XXaltjvm=参数指定的路径path,就直接用path+\jvm.dll文件做为jvm.dll的文件路径.
二:装载jvm.dll
通过第一步已经找到了jvm的路径,java通过LoadJavaVM来装入jvm.dll文件.装入工作很简单就是调用windows API函数:
LoadLibrary装载jvm.dll动态连接库.然后把jvm.dll中的导出函数JNI_CreateJavaVM和JNI_GetDefaultJavaVMInitArgs挂接到InvocationFunctions变量的CreateJavaVM和GetDefaultJavaVMInitArgs函数指针变量上。jvm.dll的装载工作宣告完成。
三:初始化jvm,获得本地调用接口,这样就可以在java中调用jvm的函数了.调用InvocationFunctions->CreateJavaVM也就是jvm中JNI_CreateJavaVM方法获得JNIEnv结构的实例.
四:运行java程序.
java程序有两种方式一种是jar包,一种是class. 运行jar,java -jar XXX.jar运行的时候,java.exe调用GetMainClassName函数,该函数先获得JNIEnv实例然后调用java类java.util.jar.JarFileJNIEnv中方法getManifest()并从返回的Manifest对象中取getAttributes("Main-Class")的值即jar包中文件:META-INF/MANIFEST.MF指定的Main-Class的主类名作为运行的主类。之后main函数会调用java.c中LoadClass方法装载该主类(使用JNIEnv实例的FindClass)。main函数直接调用java.c中LoadClass方法装载该类。如果是执行class方法。main函数直接调用java.c中LoadClass方法装载该类。

然后main函数调用JNIEnv实例的GetStaticMethodID方法查找装载的class主类中
“public static void main(String[] args)”方法,并判断该方法是否为public方法,然后调用JNIEnv实例的
CallStaticVoidMethod方法调用该java类的main方法。
另外,虚机团上产品团购,超级便宜

‘肆’ Java开发中什么情况下要用到JNI技术

为什么要使用JNI技术:

  1. java无法直接操作硬件, c/c++可以操作硬件,并且效率较高。

  2. java在视频处理,游戏渲染等方面效率不及c/c++。

  3. 避免重复造轮子, 有大量优秀的库,可以复用。

例如:java图形界面程序在最小化后,无法获取全局的键盘和鼠标事件. 需要JNI实现全局热键功能 . java里获取其他窗口的句柄, 并对其他窗口进行控制,也需要JNI技术.

使用了JNI技术缺点是会导致无法跨平台。 需要根据其他平台,再开发本地代码。

JNI实现起来有点复杂. 所以有了JNA技术, 虽然JNA很强大,但是很多功能还是需要JNI来实现的

‘伍’ Java如何调用C语言代码

Java Native Interface(JNI)是Java语言的本地编程接口,是J2SDK的一部分。在java程序中,我们可以通过JNI实现一些用java语言不便实现的功能。通常有以下几种情况我们需要使用JNI来实现。 标准的java类库没有提供你的应用程序所需要的功能,通常这些功能是平台相关的 你希望使用一些已经有的类库或者应用程序,而他们并非用java语言编写的 程序的某些部分对速度要求比较苛刻,你选择用汇编或者c语言来实现并在java语言中调用他们 下面我们开始编写HelloWorld程序,由于涉及到要编写c/c++代码因此我们会在开发中使用Microsoft VC++工具。编写java代码,我们在硬盘上建立一个hello目录作为我们的工作目录,首先我们需要编写自己的java代码,在java代码中我们会声明native方法,代码非常简单。如下所示 class HelloWorld { public native void displayHelloWorld(); static { System.loadLibrary("hello"); } public static void main(String[] args) { new HelloWorld().displayHelloWorld(); } } 注意我们的displayHelloWorld()方法的声明,它有一个关键字native,表明这个方法使用java以外的语言实现。方法不包括实现,因为我们要用c/c++语言实现它。注意System.loadLibrary("hello")这句代码,它是在静态初始化块中定义的,系统用来装载hello共享库,这就是我们在后面生成的hello.dll(如果在其他的操作系统可能是其他的形式,比如hello.so) 编译java代码 javac HelloWorld.java 生成HelloWorld.class文件 创建.h文件 这一步中我们要使用javah命令生成.h文件,这个文件要在后面的c/c++代码中用到,我们运行 javah HelloWorld。这样我们可以看到在相同目录下生成了一个HelloWorld.h文件,文件内容如下 在此我们不对他进行太多的解释。 /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloWorld */ #ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: HelloWorld * Method: displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif 编写本地实现代码 在这部分我们要用C/C++语言实现java中定义的方法,我们在VC++中新建一个Project,然后创建一个HelloWorldImp.cpp文件,内容如下 #include <jni.h> #include "HelloWorld.h" #include <stdio.h> JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) { printf("Hello world!\n"); return; } 注意我们这里include了 jni.h和刚才得到的HelloWorld.h文件。因此你要在VC++里面设置好,jni.h在JAVA_HOME/include里面。编译通过后再生成hello.dll文件。 运行java程序 把上面生成的hello.dll文件复制到我们的工作目录,这时候我们的目录中包括HelloWorld.java,HelloWorld.class和hello.dll文件。运行java HelloWorld命令,则可在控制台看到Hello world| 的输出了。运行VC++; 文件---新建---选“win32 console application”(控制台程序)---在右方设置好路径并输入工程名---确定 接下来的几个提示框点确定就行了,那是提示是否要用VC++提供的框架之类的 在左边的工作空间中选“FILEVIEW”标签项,点开“+”号,右键点击“SOURCE FILES”,选“添加文件到目录”,此即添加你要建立的C++源程序文件,会提示你没有文件,是否添加,你点是,输入文件名保存就OK了 然后SOURCE FILES下就出现了你刚才建立的*.CPP文件,双击,输入代码. 以下就是点”组建”菜单中的”编译”、”组建”等命令进行调试了。 相信你会了。 http://hi..com/%C7%E9%D4%B5and%D3%D1%D2%EA/blog/item/34084645e8560f23cefca3b7.html

‘陆’ 怎样用 jni来交互java与 c/c++

JNI是Java Native Interface的缩写,中文为JAVA本地调用。使用JNI可以很方便的用我们的Java程序调用C/C++程序。很多时候,某些功能用Java无法实现,比如说涉及到底层驱动的一些功能,这时候我们就可以利用JNI来调用C或者C++程序来实现,这就是JNI的强大之处。但是JNI也有它的缺点,使用java与本地已编译的代码交互,通常会丧失平台可移植性。
下面是一个JNI例子,调用C++输出"hello world":

第一步:创建Java类,在里面定义一个本地方法(用native关键字修饰的方法)
public native void sayHello();
第二步:使用javah命令(javah 类的全路径)生成本地方法的C++头文件
在DOS窗口中进入工程所在目录,然后执行javah com.test.TestNative命令,执行完之后就会在当前目录生成一个后缀名为.h的头文件,如com_test_TestNative.h,这个头文件是根据包名和类名来命名的。

1 /* DO NOT EDIT THIS FILE - it is machine generated */
2 #include <jni.h>
3 /* Header for class com_test_TestNative */
4
5 #ifndef _Included_com_test_TestNative
6 #define _Included_com_test_TestNative
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 /*
11 * Class: com_test_TestNative
12 * Method: sayHello
13 * Signature: ()V
14 */
15 JNIEXPORT void JNICALL Java_com_test_TestNative_sayHello
16 (JNIEnv *, jobject);
17
18 #ifdef __cplusplus
19 }
20 #endif
21 #endif

15、16行是对TestNative类中的本地方法sayHello()的声明。这个h文件相当于我们在java里面的接口,这里声明了一个 Java_com_test_TestNative_sayHello (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致。
第三步:编写C/C++本地代码,生成动态链接库文件
首先在VC6.0(当然也可以用其他工具)中创建一个dll工程---Win32 Dynamic-Link Library工程。然后将上面生成的头文件com_test_TestNative.h添加到该工程中,然后创建一个源文件引用该头文件并且实现头文件中本地函数的功能:

1 #include<iostream.h>
2 #include"com_test_TestNative.h"
3
4 JNIEXPORT void JNICALL Java_com_test_TestNative_sayHello(JNIEnv *env, jobject obj)
5 {
6 cout<<"hello world!"<<endl;
7 }

这里因为com_test_TestNative.h中引入了jni.h所以要将jni.h加入到VC6.0安装目录下的Include目录中。jni.h在JDK安装目录下的include中,同时得件include/win32中的两个头文件jawt_md.h、jni_md.h也导入到VC6.0中。
将所依赖的头文件导入之后,我们就可以构建该工程了,按F7就行了,完了会在工程目录中的Degug目录下生成一个动态链接库文件,我这里生成的是NativeCode.dll。我们就可以将该dll文件拷贝到环境变量path所包含的目录下给咱们的Java程序调用了,为了方便,我们也可以将dll所在的工程目录加入到环境变量path中去,这样可以避免每次都要拷贝的麻烦。注意修改环境变量之后要重启myeclipse。

第四步:Java调用本地函数

1 package com.test;
2
3 public class TestNative {
4 public native void sayHello();
5
6 /**
7 * @param args
8 */
9 public static void main(String[] args) {
10 System.loadLibrary("NativeCode");
11 TestNative tNative = new TestNative();
12 tNative.sayHello();
13 }
14 }

第10行是加载动态链接库,JVM只需要加载一次就可以调用了,“NativeCode”是上面生成的动态链接库的名字,不含后缀名。
运行该程序,成功打印输出了"hello world"。

阅读全文

与javajni编程相关的资料

热点内容
对弈下象棋的app哪里好 浏览:705
有什么食谱app推荐 浏览:469
python实现动态口令 浏览:823
我的世界电脑服务器地址怎么添加 浏览:850
传奇地图怎么加密到pak 浏览:977
linux删除mysql用户 浏览:755
图案设计pdf 浏览:584
pdf编辑器在线 浏览:471
华为云云耀服务器如何关机 浏览:994
数字加密的历史 浏览:613
宏杰文件夹打不开 浏览:819
施工日记app哪个好 浏览:566
什么是压缩机的排气量 浏览:538
在哪个app可以预约一科考试 浏览:634
易语言vmp加壳源码 浏览:513
阅读前端框架源码 浏览:14
我的世界命令方块传送指令 浏览:545
不能用start命令打开xp 浏览:925
text命令 浏览:30
为什么appstore经常下架游戏 浏览:91