JNI是怎样java调用c动态库
JNI是什么 java调用c动态库
JNI是JavaNativeInterface的缩写,中文为JAVA本地调用。从Java1.1开始,JavaNativeInterface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。
使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的,比如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少保证本地代码能工作在任何Java虚拟机实现下。
编写带有native声明的方法的java类
·使用javac命令编译所编写的java类
·使用javah?jnijava类名生成扩展名为h的头文件
·使用C/C++实现本地方法
·将C/C++编写的文件生成动态连接库
·ok
1)编写java程序:这里以HelloWorld为例。
代码1:
classHelloWorld{
publicnativevoiddisplayHelloWorld();
static{
System.loadLibrary("hello");
publicstaticvoidmain(String[]args){
newHelloWorld().displayHelloWorld();
声明native方法:如果你想将一个方法做为一个本地方法的话,那么你就必须声明改方法为native的,并且不能实现。其中方法的参数和返回值在后面讲述。Load动态库:System.loadLibrary("hello");加载动态库(我们可以这样理解:我们的方法displayHelloWorld()没有实现,但是我们在下面就直接使用了,所以必须在使用之前对它进行初始化)这里一般是以static块进行加载的。同时需要注意的是System.loadLibrary();的参数“hello”是动态库的名字。
2)编译
没有什么好说的了javacHelloWorld.java
3)生成扩展名为h的头文件javah?
jniHelloWorld头文件的内容:/*DONOTEDITTHISFILE-itismachinegenerated*/
1.include
/*HeaderforclassHelloWorld*/
1.ifndef_Included_HelloWorld
2.define_Included_HelloWorld
3.ifdef__cplusplus
extern"C"{
1.endif
*Class:HelloWorld
*Method:displayHelloWorld
*Signature:()V
JNIEXPORTvoidJNICALLJava_HelloWorld_displayHelloWorld(JNIEnv*,jobject);
1.ifdef__cplusplus
1.endif
2.endif
(这里我们可以这样理解:这个h文件相当于我们在java里面的接口,这里声明了一个Java_HelloWorld_displayHelloWorld(JNIEnv*,jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致)。
4)编写本地方法实现和由javah命令生成的头文件里面声明的方法名相同的方法。
代码2:
1#include"jni.h"
2#include"HelloWorld.h"
3//#includeotherheaders
4JNIEXPORTvoidJNICALLJava_HelloWorld_displayHelloWorld(JNIEnv*env,jobjectobj)
printf("Helloworld! ");
return;
注意代码2中的第1行,需要将jni.h(该文件可以在%JAVA_HOME%/include文件夹下面找到)文件引入,因为在程序中的JNIEnv、jobject等类型都是在该头文件中定义的;另外在第2行需要将HelloWorld.h头文件引入(我是这么理解的:相当于我们在编写java程序的时候,实现一个接口的话需要声明才可以,这里就是将HelloWorld.h头文件里面声明的方法加以实现。当然不一定是这样)。然后保存为HelloWorldImpl.c就ok了。
5)生成动态库
这里以在Windows中为例,需要生成dll文件。在保存HelloWorldImpl.c文件夹下面,使用VC的编译器cl成。cl-I%java_home%include-I%java_home%includewin32-LDHelloWorldImp.c-Fehello.dll注意:生成的dll文件名在选项-Fe后面配置,这里是hello,因为在HelloWorld.java文件中我们loadLibary的时候使用的名字是hello。当然这里修改之后那里也需要修改。另外需要将-I%java_home%include-I%java_home%includewin32参数加上,因为在第四步里面编写本地方法的时候引入了jni.h文件。
6)运行程序javaHelloWorld就ok.
下面是一个简单的例子实现打印一句话的功能,但是用的c的printf最终实现。一般提供给java的jni接口包括一个so文件(封装了c函数的实现)和一个java文件(需要调用path的类)。
1.JNI的目的是使java方法中能够调用c实现的一些函数,比如以下的java类,就需要调用一个本地函数testjni(一般声明为privatenative类型),首先需要创建文件weiqiong.java,内容如下:
classweiqiong{static{System.loadLibrary("testjni");//载入静态库,test函数在其中实现}privatenativevoidtestjni();//声明本地调用publicvoidtest(){testjni();}publicstaticvoidmain(Stringargs[]){weiqionghaha=newweiqiong();haha.test();}}
2.然后执行javacweiqiong.java,如果没有报错,会生成一个weiqiong.class。
3.然后设置classpath为你当前的`工作目录,如直接输入命令行:setclasspath=weiqiong.class所在的完整目录(如c: est)再执行javahweiqiong,会生成一个文件weiqiong.h文件,其中有一个函数的声明如下:
JNIEXPORTvoidJNICALLJava_weiqiong_testjni(JNIEnv*,jobject);
4.创建文件testjni.c将上面那个函数实现,内容如下:
1.include
2.include
JNIEXPORTvoidJNICALLJava_weiqiong_testjni(JNIEnv*env,jobjectobj){printf("haha---------gointoc!!! ");}
5.为了生成.so文件,创建makefile文件如下:
libtestjni.so:testjni.omakefilegcc-Wall-rdynamic-shared-olibtestjni.sotestjni.otestjni.o:testjni.cweiqiong.hgcc-Wall-ctestjni.c-I./-I/usr/java/j2sdk1.4.0/include-I/usr/java/j2sdk1.4.0/include/linuxcl:rm-rf*.o*.so注意:gcc前面是tab空,j2sdk的目录根据自己装的j2sdk的具体版本来写,生成的so文件的名字必须是loadLibrary的参数名前加“lib”。
6.exportLD_LIBRARY_PATH=.,由此设置library路径为当前目录,这样java文件才能找到so文件。一般的做法是将so文件copy到本机的LD_LIBRARY_PATH目录下。
7.执行javaweiqiong,打印出结果:“haha---------gointoc!!!”
javascript 中(function{})()这种写法什么意思?
最近在整理javascript 学习,发现这个问题了 ,在网上发现这么个解释 最清楚 最明白 ;
(function(){})()
相当于先定义 function xx(){},后调用 xx();
()是最高优先级的,所以先执行function(){},
这个定义了一个匿名函数,等于xx=function(www.diannao114.cn){}
接着就是调用xx()了;
给个例子
JScript codefunctionf1(a)
{ alert(a);
functionf2(a)
{ returnfunction(){ alert(a); }
}这里的var x=f2 就等于把函数传递给了f2,然后要执行这个函数,就必须加() 也就是x();
也就是f2()
还是(function f2(a){
return function(){
alert(a);
另外还有一个问题就是命名空间的问题
YY = YY||{};---声明一个叫YY的命名空间(定义一个全局的变量)
(function() {
YY.Lang=function() {------声明一个叫YY.Lang的命名空间(通过全局变量的增加属性的方式把闭包里的对象传到全局变量中,实现代码封装的效果)
isUndefined: function(o) {
return typeof o === 'undefined';
isString: function(o) {
return typeof o === 'string';
---调用方法
alert(YY.Lang.isString('test me'));
这时候就有人不明了,楼上为什么要加(function() { 和)(); 最外面的这两行,有什么用啊?
JScript codeYY=YY||{}; //---声明一个叫YY的命名空间(定义一个全局的变量)
function() { YY.Lang=function() {
//------声明一个叫YY.Lang的命名空间(通过全局变量的增加属性的方式把闭包里的对象传到全局变量中,实现代码封装的效果) isUndefined:function(o) {returntypeofo==='undefined'; },
isString:function(o) {returntypeofo==='string'; } }; }
//---调用方法
alert(YY.Lang.isString('test me'));
疑问在这: 注释掉这两行有什么不一样的呢?不就是申明吗,为什么要用()()执行一下啊?
答:
(function(){})()意思是立即执行前一个括号里的function,相当于是一个匿名函数;由于里面的代码的执行,定义了YY.Lang这个对象,所以可以执行alert(YY.Lang.isString('test me'));调用isString方法。
但是,如果按照你写的
functionaa(){..};//只是定义了一个叫aa的函数,但是并没有执行
alert(YY.Lang.isString('test me'));//执行的时候会报找不到isString的方法。
这么写有什么好处??
(function{})()的写法有个好处,就是能很好的利用javascript的变量的可见范围为执行脚本时节省空间。例如以下写法1和写法2达到的目的是一样的,但是写法1的由于a变量的可见范围只是在匿名函数体内,所以a在执行完这个匿名函数后就释放空间了。但是写法2会一直存在该页面中。
写法1:
JScript code(function(){vara=2; alert(a); })();
写法2:
JScript codevara=2; alert(a);
Java服务器软件工程师试题
Java服务器软件工程师试题一、 选择题1. 欲构造ArrayList类的一个实例,此类继承了List接口,下列哪个方法是正确的 ( )A ArrayList myList=new Object(); B List myList=new ArrayList(); C ArrayList myList=new List(); D List myList=new List(); 2. paint()方法使用哪种类型的参数? ( )A Graphics B Graphics2D C String D Color 3. 指出下列程序运行的结果( ) public class Example{ String str=new String("good"); char[]ch={'a','b','c'}; public static void main(String args[]){ Example ex=new Example(); ex.change(ex.str,ex.ch); System.out.print(ex.str+" and "); Sytem.out.print(ex.ch); } public void change(String str,char ch[]){ str="test ok"; ch[0]='g'; } } A good and abc B good and gbc C test ok and abc D test ok and gbc 4. 要从文件" file.dat"文件中读出第10个字节到变量C中,下列哪个方法适合? ( )A FileInputStream in=new FileInputStream("file.dat"); in.skip(9); int c=in.read(); B FileInputStream in=new FileInputStream("file.dat"); in.skip(10); int c=in.read(); C FileInputStream in=new FileInputStream("file.dat"); int c=in.read(); D RandomAccessFile in=new RandomAccessFile("file.dat"); in.skip(9); int c=in.readByte(); 5. 给出下面代码,那个语句是正确的?( )public class Person{ static int arr[] = new int[10]; public static void main(String a[]) { System.out.println(arr[1]); } } A 编译时将产生错误; B 编译时正确,运行时将产生错误; C 输出零; D 输出空。 7. 执行下面的hql查询,关于返回值的说法,正确的是( ) select u.username,u.userid from com.x.entity.User u where u is not nullA语法错误,不能执行B返回一个类型为List的实例C返回一个数组D当返回结果只有一条时,返回一个数组8. 下面的程序执行后没有报错,但数据总保存不到数据库,最可能的原因 ( )public static void imain(String[] args){ SessionFactory sf=new Configration().configure().buildSessionFactory(); Session session=sf.openSession(); Medal medal=new Medal(); medal.setOwner(“totong”); medal.setType(“Gold medal”); session.save(user); session.close();}A配置文件配置有误B没有在配置文件中包含对映射文件的声明C配置文件配置有误D没有对持久化操作捕捉异常E没有开启事务二、多项选择题1. 执行下列代码后,哪个结论是正确的 String[] s=new String[10]; ( )A s[10] 为 ""; B s[9] 为 null; C s[0] 为 未定义 D s.length 为10 2. 下列哪个方法可用于创建一个可运行的类? ( )A public class X implements Runable{ public void run(){ ......} } B public class X implements Thread{ public void run(){ ......} } C public class X implements Thread{ public int run(){ ......} } D public class X implements Runable{ protected void run(){ ......} } E.public class X implements Thread{ public void run(){ ......} } 3. 下面哪个方法可以在任何时候被任何线程调用? ( )A notify() B wait() C notifyAll() D sleep() E.yield() F.synchronized(this) 4. 构造BufferedInputStream的合适参数是哪个? ( )A BufferedInputStream B BufferedOutputStream C FileInputStream D FileOuterStream E. File 5. 指出下列哪个方法与方法public void add(int a){}为合理的重载方法。 ( )A public int add(int a) B public void add(long a) C public void add(int a,int b) D public void add(float a) 6. JDBC可以做哪三件 ( )A 与数据库建立连接B 通过JDBC-API向数据库发送SQL语句C通过JDBC-API执行SQL语句D进行实体关系的映射 www.diannao114.cn7. Hibernate通过____接口,____接口和Type层次体系来访问元数据。( )A ClassMetadataB CollectionMetadataC MetadataD CollectionMeta三,问答题1.执行下列代码后的结果是什么? int x,a=2,b=3,c=4; x=++a+b+++c++;2.简述什么是设计模式,请描述你用过的几种设计模式!3.从JAVA的角度理解,什么是重构?5.abstractclass和interface有什么区别? 6.error和exception有什么区别?7.下列程序中构造了一个SET并且调用其方法add(),输出结果是?public class A{ public int hashCode(){return 1;} public Boolean equals(Object b){return true} public static void main(String args[]){ Set set=new HashSet(); set.add(new A()); set.add(new A()); set.add(new A()); System.out.println(set.size()); } } 8、请说出你所知道的线程同步的方法9、如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算
甲骨文分羹Android 谷歌借机升级"山寨"Java
导读:近年来,各种专利诉讼案频发,各个厂商对自有专利的所有权和使用权越发的重视,一方是维护自己的权利、增加营收范围,一方是防止同行分享自己辛苦的经营成果,孰是孰非可谓见仁见智。
天极网4月26日消息,在4月25日的甲骨文起诉GoogleAndroid系统侵权案的审判中,一名Android前任工程师伯恩斯坦(DanBornstein)承认,去年在遭到起诉后,他曾负责在Android中移除了部分Java技术。
伯恩斯坦表示,Android是一个“活的项目”,随时都在修改调整,并称这部分Java技术是通过瑞士的一个软件开发承包商Noser带到Android中的,当时Android方面曾建议该公司哪些技术可以移植到Android,哪些则不可以。
(甲骨文分羹Android谷歌可借机升级“山寨”Java)
事件回顾
甲骨文在收购了Sun公司并获得Java专利权后,于2010年8月将Google告上法庭,指控其Android操作系统侵犯了Java技术专利,并要求赔偿10亿美元。
在今年3月底,Google表示愿意向甲骨文支付两项专利的2011年费用,共计280万美元。至于未来的赔偿,Google提议将Android营收0.5%作为一项专利的费用,此专利今年12月到期;另外将0.015%的营收作为第二项专利的费用,此专利2018年4月到期。但甲骨文对此的回应则是“Google开出的赔偿额度太低了”。
Google表态:所用技术无需授权
3月25日,“Android之父”Google高层安迪·鲁宾也在法庭上作证,他强调,“Android开发中所使用了Java部分不需要专利授权的技术,所以无需支付专利费,也不需要获得甲骨文的授权。”
有报道称,在去年专利诉讼发生的前几周,一封Google内部邮件透露,当时Google创始人拉里·佩吉(LarryPage)和塞尔吉·布林(SergeyBrin)曾要求“调查哪种技术可以成为Android中Java的替代方案”,而最终的讨论结果是“我们寻找了许多方案都不行,因此得出结论:我们要商讨Java授权。”
分羹Android
法庭文件披露,谷歌曾经在2010年预测,到2013年,来自Android的相关收入(包括广告、软件产品、数字音乐消费等)将会高达37亿美元。
甲骨文如此大动干戈的索要Java技术授权费,一定程度上也是看准了Android的巨大价值潜力,而Google方面千方百计的推脱责任,或许也是在为继续寻求Java替代方案拖延时间,或者想要争取更低的授权费用。
近年来,各种专利诉讼案频发,各个厂商对自有专利的所有权和使用权越发的重视,一方是维护自己的权利、增加营收范围,一方是防止同行分享自己辛苦的经营成果,孰是孰非可谓见仁见智,而双方为之付出的巨大精力和财力是显而易见的。
随着诉讼的发展进程,Google方面并不占据优势,若最终甲骨文赢得官司,甲骨文则可获得上亿美元的专利费,而Google也有机会将其“山寨”Java升级为“正版”Java,对于Android系统的完善也不失是件好事。而目前Google最应该做的就是想办法说服甲骨文降低专利授权费用。
Java语言中面向对象是什么意思
何谓面向对象是什么意思呢?
面向对象程序设计是将人们认识世界过程中普遍采用的思维方法应用到程序设计中。对象是现实世界中存在的事物,它们是有形的,如某个人、某种物品;也可以是无形的,如某项计划、某次商业交易。对象是构成现实世界的一个独立单位,人们对世界的认识,是从分析对象的特征入手的。
对象的特征分为静态特征和动态特征两种。静态的特征指对象的外观、性质、属性等;动态的特征指对象具有的功能、行为等。客观事物是错综复杂的,但人们总是从某一目的出发,运用抽象分析的能力,从众多的特征中抽取最具代表性、最能反映对象本质的若干特征加以详细研究。
人们将对象的静态特征抽象为属性,用数据来描述,在Java语言中称之为变量;人们将对象的动态特征抽象为行为,用一组代码来表示,完成对数据的操作,在Java语言中称之为方法,。一个对象由一组属性和一组对属性进行操作的方法构成。
Java语言优点介绍
Java语言的优点
Java语言是一种优秀的编程语言。它最大的优点就是与平台无关,在Windows 9x、Windows NT、Solaris、Linux、MacOS以及其它平台上,都可以使用相同的代码。“一次编写,到处运行”的特点,使其在互联网上被广泛采用。
由于Java语言的设计者们十分熟悉C++语言,所以在设计时很好地借鉴了C++语言。可以说,Java语言是一种比C++语言“还面向对象”的一种编程语言。Java语言的语法结构与C++语言的语法结构十分相似,这使得C++程序员学习Java语言更加容易。
当然,如果仅仅是对C++改头换面,那么就不会有今天的Java热了。Java语言提供的一些有用的新特性,使得使用Java语言比C++语言更容易写出“无错代码”。
这些新特性包括:
1、提供了对内存的自动管理,程序员无需在程序中进行分配、释放内存,那些可怕的内存分配错误不会再打扰设计者了;
2、去除了C++语言中的令人费解、容易出错的“指针”,用其它方法来进行弥补;
3、避免了赋值语句(如a = 3)与逻辑运算语句(如a = = 3)的混淆;
4、取消了多重继承这一复杂的概念。
【JNI是怎样java调用c动态库】相关文章:
4.汇编调用C函数