⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch10.htm

📁 JAVA Developing Professional JavaApplets
💻 HTM
📖 第 1 页 / 共 5 页
字号:
is hidden within the native library. A native method appears toJava like all other real Java methods. In fact, all the Java modifiers(public, private, and so forth) apply to native methods as well.<H2><A NAME="WritingNativeMethods"><FONT SIZE=5 COLOR=#FF0000>WritingNative Methods</FONT></A></H2><P>The Java runtime was implemented in the C programming language,so currently the only native language supported is C. The entrypoints into a C library that can be called from Java are called<I>stubs</I>. When you execute a native method call, a stub isentered. Java tries to ease the transition into native code bysupplying a tool to generate a C header file and stub module.<BR><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD><B>Note</B></TD></TR><TR VALIGN=TOP><TD><BLOCKQUOTE>Any language that can link with and be called by C can be used to implement a native method. The C language is needed only to provide the actual interface with Java. Any additional, non-Java processing could be done in another language, such as Pascal.</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><H3><A NAME="UsingJavah">Using <TT><FONT SIZE=4 FACE="Courier">Javah</TT></FONT></A></H3><P><TT>Javah</TT> is the tool used togenerate C files for Java classes; here's how you use it:<BLOCKQUOTE><TT>javah [options] <I>class</I></TT></BLOCKQUOTE><P>Table 10.1 briefly lists the options available. By default, <TT>javah</TT>will create a C header (.h) file in the current directory foreach class listed on the command line. Class names are specifiedwithout the trailing <TT>.class</TT>.Therefore, to generate the header for SomeName.class, use thefollowing command:<BLOCKQUOTE><TT>javah SomeName<BR></TT></BLOCKQUOTE><P><CENTER><B>Table 10.1. </B><TT><B>Javah</FONT></B></TT><B>options.</B></CENTER><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD WIDTH=185><I>Option</I></TD><TD WIDTH=308><I>Description</I></TD></TR><TR VALIGN=TOP><TD WIDTH=185><TT>-verbose</TT></TD><TD WIDTH=308>Causes progress strings to be sent to stdout</TD></TR><TR VALIGN=TOP><TD WIDTH=185><TT>-version</TT></TD><TD WIDTH=308>Prints the version of javah</TD></TR><TR VALIGN=TOP><TD WIDTH=185><TT>-o <I>outputfile</I></TT></TD><TD WIDTH=308>Overrides default file creation;uses only this file</TD></TR><TR VALIGN=TOP><TD WIDTH=185><TT>-d <I>directory</I></TT></TD><TD WIDTH=308>Overrides placement of output in current directory</TD></TR><TR VALIGN=TOP><TD WIDTH=185><TT>-td <I>tempdirectory</I></TT></TD><TD WIDTH=308>Overrides default temp directory use</TD></TR><TR VALIGN=TOP><TD WIDTH=185><TT>-stubs</TT></TD><TD WIDTH=308>Creates C code module instead of header module</TD></TR><TR VALIGN=TOP><TD WIDTH=185><TT>-classpath <I>path</I></TT></TD><TD WIDTH=308>Overrides default classpath</TD></TR></TABLE></CENTER><P><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD><B>Note</B></TD></TR><TR VALIGN=TOP><TD><BLOCKQUOTE>If the class you want is within a package, then the package name must be specified along with the class name: <TT>javah java.net.Socket</TT>. In addition, <TT>javah</TT> will prefix the package name to the output filename: <TT>java_net_Socket.h</TT>.</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><P>Listing 10.1 is a simple class with native methods. The classwas chosen because it uses most of the Java types. Compile thisclass and pass it to <TT>javah</TT>.<HR><BLOCKQUOTE><B>Listing 10.1. A simple class using native methods.<BR></B></BLOCKQUOTE><BLOCKQUOTE><TT>public class Demonstration<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;public String publicName;<BR>&nbsp;&nbsp;&nbsp;&nbsp;private String privateName;<BR>&nbsp;&nbsp;&nbsp;&nbsp;public static String publicStaticName;<BR>&nbsp;&nbsp;&nbsp;&nbsp;private static String privateStatucName;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public native void method1();<BR>&nbsp;&nbsp;&nbsp;&nbsp;public native int method2(boolean b, byteby, char c, short s);<BR>&nbsp;&nbsp;&nbsp;&nbsp;public native byte[] method3(byte data[],boolean b[]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;public native String[] method4(int num,long l, float f, double d);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;static<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.loadLibrary(&quot;Demonstration&quot;);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}</TT></BLOCKQUOTE><HR><P>The <TT>javah</TT> output of the aboveclass is in Listing 10.2.<HR><BLOCKQUOTE><B>Listing 10.2. </B><TT><B>Javah</FONT></B></TT><B>output header of Demonstration class.<BR></B></BLOCKQUOTE><BLOCKQUOTE><TT>/* DO NOT EDIT THIS FILE - it is machinegenerated */<BR>#include &lt;native.h&gt;<BR>/* Header for class Demonstration */<BR><BR>#ifndef _Included_Demonstration<BR>#define _Included_Demonstration<BR>struct Hjava_lang_String;<BR><BR>typedef struct ClassDemonstration {<BR>&nbsp;&nbsp;&nbsp;&nbsp;struct Hjava_lang_String *publicName;<BR>&nbsp;&nbsp;&nbsp;&nbsp;struct Hjava_lang_String *privateName;<BR>/* Inaccessible static: publicStaticName */<BR>/* Inaccessible static: privateStatucName */<BR>} ClassDemonstration;<BR>HandleTo(Demonstration);<BR><BR>#ifdef __cplusplus<BR>extern &quot;C&quot; {<BR>#endif<BR>__declspec(dllexport) void Demonstration_method1(struct HDemonstration*);<BR>__declspec(dllexport) long Demonstration_method2(struct HDemonstration*,/*boolean*/ long,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char,unicode,short);<BR>__declspec(dllexport) HArrayOfByte *Demonstration_method3(structHDemonstration *,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HArrayOfByte *,HArrayOfInt *);<BR>__declspec(dllexport) HArrayOfString *Demonstration_method4(structHDemonstration *,long,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int64_t,float,double);<BR>#ifdef __cplusplus<BR>}<BR>#endif<BR>#endif</TT></BLOCKQUOTE><HR><P>The class has been transformed into a C structure. Each classmember is represented, except for static fields. Representationin a structure has an interesting side effect. Native methodshave access to all non-static fields, including private classmembers. You are free to read and alter any member of the class.<P>Now focus your attention on the four native method prototypes.Each method has been renamed by prefixing the class name to themethod name. Had this class been contained in a package, the packagename also would have been added. Each method has an additionalargument. All native methods have a <TT>this</TT>pointer that allows the function to access the variables of itsassociated class. This argument is often referred to as an &quot;automatic&quot;parameter. Java will add this parameter to your methods automatically.<P>The final piece to the puzzle is the <TT>HandleTo()</TT>macro. Every object in Java is represented in a structure calleda JHandle. The format of this structure for the Demonstrationclass is as follows:<BLOCKQUOTE><TT>struct HDemonstration<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;ClassDemonstration *obj;<BR>&nbsp;&nbsp;&nbsp;&nbsp;methodtable *methods;<BR>}</TT></BLOCKQUOTE><P>The <TT>HandleTo()</TT> macro namesthe JHandle by adding an <I>H</I> to the passed name. To accessany member of a JHandle class, you must dereference it with the<TT>unhand()</TT> macro. This macrohas the opposite effect of <TT>HandleTo()</TT>.The following line retrieves a string member from the Demonstrationclass:<BLOCKQUOTE><TT>Hjava_lang_String str = unhand(demoPtr)-&gt;publicName;</TT></BLOCKQUOTE><P>The code for the <TT>unhand()</TT>macro shows the conversion:<BLOCKQUOTE><TT>#define unhand(o)&nbsp;&nbsp;((o)-&gt;obj)</TT></BLOCKQUOTE><P>Structure member <TT>obj</TT> is obviouslythe class structure, but what of the other structure member?<P>Typically, structure member methods will contain a pointer toan internal Java runtime structure that represents all the informationon a class. This includes the Java byte codes, the exception table,any defined constants, and the parent class. There are times,however, when the variable is not a pointer at all. Java has reservedthe lower 5 bits of the pointer for flags. If all 5 bits are zero,then the value is a pointer. If the lower 5 bits are non-zero,then the methods field becomes a typecode. You will encountertypecodes whenever you handle arrays.<H3><A NAME="JavaArrays">Java Arrays</A></H3><P>Arrays are handled uniquely in Java. They are considered objects,though they have no methods. Arrays occupy the realm somewherebetween basic runtime types, such as <TT>int</TT>or <TT>long</TT>, and formal classobjects. In Java, basic types are represented in a compact form.It would be inefficient to have all the class baggage carriedaround with something simple like an integer. When you need torepresent an <TT>int</TT> as an object,you use a wrapper class, such as class Integer. This is why the&quot;wrapper&quot; classes are necessary. Arrays are much morecomplicated than numbers because they have variable length andmultiple members. Like class objects, their storage is best representedby a C structure. Unlike class objects, arrays don't have methods.It was decided that the <TT>methodtable</TT>pointer could be better used as a scalar quantity for arrays.<P>The upper 27 bits of the pointer represent the length of the array,and the lower 5 bits represent the type of data the array contains.All the runtime types are actually represented in the lower 4bits. The fifth bit is reserved for compiler usage. Table 10.2shows the encoding of the lower 4 flag bits and their meanings.<BR><P><CENTER><B>Table 10.2. Type encoding.</B></CENTER><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD WIDTH=82><CENTER><I>Encoding</I></CENTER></TD><TD WIDTH=175><I>Type</I></TD></TR><TR VALIGN=TOP><TD WIDTH=82><CENTER>0000</CENTER></TD><TD WIDTH=175>T_NORMAL_OBJECT</TD></TR><TR VALIGN=TOP><TD WIDTH=82><CENTER>0001</CENTER></TD><TD WIDTH=175>Unused</TD></TR><TR VALIGN=TOP><TD WIDTH=82><CENTER>0010</CENTER></TD><TD WIDTH=175>T_CLASS</TD></TR><TR VALIGN=TOP><TD WIDTH=82><CENTER>0011</CENTER></TD><TD WIDTH=175>Unused</TD></TR><TR VALIGN=TOP><TD WIDTH=82><CENTER>0100</CENTER></TD><TD WIDTH=175>T_BOOLEAN</TD></TR><TR VALIGN=TOP><TD WIDTH=82><CENTER>0101</CENTER></TD><TD WIDTH=175>T_CHAR</TD></TR><TR VALIGN=TOP><TD WIDTH=82><CENTER>0110</CENTER></TD><TD WIDTH=175>T_FLOAT</TD></TR><TR VALIGN=TOP><TD WIDTH=82><CENTER>0111</CENTER></TD><TD WIDTH=175>T_DOUBLE</TD></TR><TR VALIGN=TOP><TD WIDTH=82><CENTER>1000</CENTER></TD><TD WIDTH=175>T_BYTE</TD></TR><TR VALIGN=TOP><TD WIDTH=82><CENTER>1001</CENTER></TD><TD WIDTH=175>T_SHORT</TD></TR><TR VALIGN=TOP><TD WIDTH=82><CENTER>1010</CENTER></TD><TD WIDTH=175>T_INTEGER</TD></TR><TR VALIGN=TOP><TD WIDTH=82><CENTER>1011</CENTER></TD><TD WIDTH=175>T_LONG</TD></TR></TABLE></CENTER><P><P>There are macros to help you read both the type bits and the length.The <TT>obj_flags()</TT> macro willreturn the flag bits, and <TT>obj_length()</TT>will return the array length. Both must be passed a JHandle pointer:<BLOCKQUOTE><TT>if ( obj_flags( demoPtr ) != T_NORMAL_OBJECT)<BR>&nbsp;&nbsp;&nbsp;length = obj_length( demoPtr );</TT></BLOCKQUOTE><P>In practice, you will not need to check the type bits becauseJava will create and pass one of the standard array structures.You can see this in <TT>Demonstration_method3()</TT>.The parameter <TT>byte[]</TT> hasbeen passed as an HArrayOfByte pointer. All the standard arraystructures have a single member: <TT>body[1]</TT>.Table 10.3 lists all the array structures and their contents.To access an array member, dereference the JHandle and index intothe body array. The following line reads the fifth byte from aJava byte array:<BLOCKQUOTE><TT>char fifthByte = unhand(hByte)-&gt;body[4];</TT></BLOCKQUOTE><P>As you can see, Java arrays are zero-based just like C arrays.<BR><P><CENTER><B>Table 10.3. Standard array structures.</B></CENTER><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD WIDTH=122><I>Structure</I></TD><TD WIDTH=154><I>Contents</I></TD></TR><TR VALIGN=TOP><TD WIDTH=122>ArrayOfByte</TD><TD WIDTH=154>char body[1]</TD></TR><TR VALIGN=TOP><TD WIDTH=122>ArrayofChar</TD><TD WIDTH=154>unicode body[1]</TD></TR><TR VALIGN=TOP><TD WIDTH=122>ArrayOfShort</TD><TD WIDTH=154>signed short body[1]</TD></TR><TR VALIGN=TOP><TD WIDTH=122>ArrayOfInt</TD><TD WIDTH=154>long body[1]</TD></TR><TR VALIGN=TOP><TD WIDTH=122>ArrayOfLong</TD><TD WIDTH=154>int64_t body[1]</TD></TR><TR VALIGN=TOP><TD WIDTH=122>ArrayOfFloat</TD><TD WIDTH=154>float body[1]</TD></TR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -