<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0056)http://ecapital.myetang.com/java/tutorial/java01/j13.htm -->
<HTML><HEAD><TITLE>易都网--Java应用程序设计和开发环境</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<SCRIPT language=javascript>
<!--
function setBgColor(color){window.thetd.bgColor=color;}
function setFontSize(size){window.thetd.style.fontSize=size;}
function setFontColor(color){window.thetd.style.color=color;}
//-->
</SCRIPT>
<STYLE type=text/css>H4 {
LINE-HEIGHT: 18pt; TEXT-ALIGN: center
}
H3 {
LINE-HEIGHT: 18pt; TEXT-ALIGN: center
}
P {
LINE-HEIGHT: 18pt
}
.f1 {
COLOR: #000000; FONT-SIZE: 11pt
}
</STYLE>
<META content="MSHTML 5.00.2614.3500" name=GENERATOR></HEAD>
<BODY bgColor=#ffffff>
<SCRIPT language=JavaScript>
<!--
var currentpos,timer;
function initialize()
{
timer=setInterval("scrollwindow()",10);
}
function sc(){
clearInterval(timer);
}
function scrollwindow()
{
currentpos=document.body.scrollTop;
window.scroll(0,++currentpos);
if(currentpos!=document.body.scrollTop) sc();
}
document.onmousedown=sc
document.ondblclick=initialize
//-->
</SCRIPT>
<TABLE border=0 cellPadding=0 cellSpacing=0 width="100%">
<TBODY>
<TR bgColor=#339966>
<TD height=18 width="100%">
<P align=center><FONT color=#ffffff size=2>文字: <SELECT name=selcolor
onchange=setFontColor(this.value); size=1
style="HEIGHT: 21px; WIDTH: 65px"> <OPTION
style="BACKGROUND-COLOR: #ffffff" value=#FFFFFF></OPTION> <OPTION
style="BACKGROUND-COLOR: #ffffcc" value=#FFFFCC></OPTION> <OPTION
style="BACKGROUND-COLOR: #ffcccc" value=#FFCCCC></OPTION> <OPTION
style="BACKGROUND-COLOR: #66ffff" value=#66FFFF></OPTION> <OPTION
style="BACKGROUND-COLOR: #dfdfdf" value=#DFDFDF></OPTION> <OPTION
selected style="BACKGROUND-COLOR: #000000" value=#000000></OPTION>
<OPTION style="BACKGROUND-COLOR: #3333cc" value=#3333CC></OPTION>
<OPTION style="BACKGROUND-COLOR: #c4c4e1" value=#C4C4E1></OPTION>
<OPTION style="BACKGROUND-COLOR: #339999" value=#339999></OPTION>
<OPTION style="BACKGROUND-COLOR: #339900" value=#339900></OPTION>
<OPTION style="BACKGROUND-COLOR: #993300" value=#993300></OPTION>
<OPTION style="BACKGROUND-COLOR: #fcc66b" value=#FCC66B></OPTION></SELECT>
背景: <SELECT name=select onchange=setBgColor(this.value); size=1
style="HEIGHT: 21px; WIDTH: 65px"> <OPTION selected
style="BACKGROUND-COLOR: #ffffff" value=#FFFFFF></OPTION> <OPTION
style="BACKGROUND-COLOR: #ffffcc" value=#FFFFCC></OPTION> <OPTION
style="BACKGROUND-COLOR: #ffcccc" value=#FFCCCC></OPTION> <OPTION
style="BACKGROUND-COLOR: #66ffff" value=#66FFFF></OPTION> <OPTION
style="BACKGROUND-COLOR: #dfdfdf" value=#DFDFDF></OPTION> <OPTION
style="BACKGROUND-COLOR: #000000" value=#000000></OPTION> <OPTION
style="BACKGROUND-COLOR: #3333cc" value=#3333CC></OPTION> <OPTION
style="BACKGROUND-COLOR: #c4c4e1" value=#C4C4E1></OPTION> <OPTION
style="BACKGROUND-COLOR: #339999" value=#339999></OPTION> <OPTION
style="BACKGROUND-COLOR: #339900" value=#339900></OPTION> <OPTION
style="BACKGROUND-COLOR: #993300" value=#993300></OPTION> <OPTION
style="BACKGROUND-COLOR: #fcc66b" value=#FCC66B></OPTION></SELECT>
字号: <SELECT name=selsize onchange=setFontSize(this.value); size=1
style="HEIGHT: 21px; WIDTH: 65px; fontsize: 12pt"> <OPTION
value=9pt>9pt</OPTION> <OPTION selected value=10pt>10pt</OPTION> <OPTION
value=11pt>11pt</OPTION> <OPTION value=12pt>12pt</OPTION> <OPTION
value=13pt>13pt</OPTION> <OPTION value=14pt>14pt</OPTION> <OPTION
value=15pt>15pt</OPTION> <OPTION value=16pt>16pt</OPTION></SELECT>
</FONT></P></TD></TR>
<TR>
<TD width="100%">
<TABLE bgColor=#eeeeee border=0 cellPadding=3 cellSpacing=0
width="100%"><TBODY>
<TR>
<TD class=f1 id=thetd width="100%">
<P> </P>
<H3>第十三章 native方法</H3>
<P> 这一章讨论Java与C的接口问题。目前在Java中使用C编写的函数有两种方法,本章将分别予以介绍。</P>
<H4> 13.1 引入native方法的原因</H4>
<P> Java作为一种新兴的语言,在短时间内迅速崛起,给人们留下了深刻的印象。然而,它的功能毕竟还很不完善。而C语言不但拥有丰富的函数、众多的熟练程序员,而且有多年应用积累下来的宝贵经验和资源。另外某些工作无论从功能还是效率来考虑用C来做都更合适些。这就带来了Java与C的接口问题。</P>
<P> 诚然,C的引入对Java的多平台适应性是有影响的。使用了native方法的Java程序只能在编译它的平台上运行——这或许就是“native方法”这个名字的由来。“native”的原义是“本地的”,而对native方法,我们可以称为“原生方法”,也即指用C实现的方法。</P>
<P> 在Java这样一种纯面向对象的语言中引用C程序不是件简单的事情。由于C语言的灵活性,Java的设计者们不得不采用一些限制手段来防止产生安全问题。因此,使用native方法的过程可能比你设想的要复杂的多。但是,只要你按我们介绍,按部就班地去做,一样可以轻松地达到目的。</P>
<P> 原生方法技术也在不断地发展。在1.0.2版本中使用的原生方法接口在性能上有所欠缺,不利于垃圾收集的进行。1.1.1版本已经引入了一种新的原生方法接口,叫做Java
Native Interface,简称JNI。但旧的接口仍被保留。二者的关系可以归纳为三点:</P>
<P> (1)可以用新版的JDK按旧的接口办法使用原生方法。</P>
<P> (2)用旧的JDK生成的程序和动态链接库可以在新版的虚拟机上运行(即可以用新版的解释器来解释执行)。</P>
<P> (3)新旧两种接口办法在编程细节和动态链接库生成步骤上略有差别。</P>
<P> 本章将对新旧两种办法给予介绍。</P>
<P> 最后需要附带提一句,由微软公司开发的Java软件开发包SDK在native方法的实现上有所改动,与SUN公司的JDK提供的实现有一些差异。本文将以SUN公司的JDK为准。如果读者使用的是微软公司的开发环境,请参阅有关文档。</P>
<H4> 13.2 使用native方法的步骤</H4>
<P> 这一节介绍旧的原生方法接口办法。在1.0x版本和1.1版本中此办法均适用。</P>
<P> 在程序中使用native方法,大致需要5个步骤。为了说明问题,我们举一个很简单的例子。这个例子的功能是用C语言的printf()函数打印一个字符串常量。下面我们依次序进行。</P>
<H5> 13.2.1 创建Java源文件和.class文件</H5>
<P> 这一步与我们做普通Java程序的工作相似。native方法不是直接嵌入在Java代码中的,在Java源码中只列出原型。具体的实现(C文件)将被编译成动态链接库的一部分,由Java解释器装入并调用其中的native方法。因此,在程序中要做两件事:一是声明native方法,二是装入动态链接库(在Unix系统下应叫共享库)。下面我们来看看具体就怎样做(例13.1)。</P>
<P> 例13.1 DispDemo.java。</P>
<P> 1:class DispDemo{<BR> 2: static{<BR> 3:
Runtime.getRuntime().loadLibrary("dispdll");<BR> 4: }<BR> 5:
public native void display();<BR> 6: }</P>
<P> DispDemo是我们定义的一个类。在这个类中,有一个方法display()是用C语言实现的,也就是native方法。我们在第5行对它进行了声明。</P>
<P> 第2至4行是一个语句,它的功能是装入动态链接库。它被static修饰符所修饰,因而它只能在DispDemo类被装入执行时执行一次。即使我们需要创建多个DispDemo类的对象,也只需装入动态链接库一次。装入动态链接库的工作由方法loadLibrary()完成。在语言类库java.lang中,System类和Runtime类中都定义了这个方法。这里用Runtime类的对象来调用它。我们也可以把第三行的语句改为</P>
<P> System.loadLibrary("dispdll");</P>
<P>一样可以达到目的。</P>
<P> 为了调用native方法,我们又创建了一个类DispDemoMain(例13.2)。它包含Java解释器入口——main方法。它的功能是创建一个DispDemo对象并调用后者的native方法。</P>
<P> 例 13.2 DispDemoMain.java。</P>
<P> 1:class DispDemoMain{<BR> 2: public static void main(String
args[]){<BR> 3: ispDemo().display();<BR>�