📄 appendixa.html
字号:
}
<font color=#0000ff>public</font> <font color=#0000ff>class</font> ShowCallback {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String args[])
<font color=#0000ff>throws</font> InterruptedException {
<font color=#0000ff>boolean</font> ok = User32.EnumWindows(
<font color=#0000ff>new</font> EnumWindowsProc(), 0);
<font color=#0000ff>if</font>(!ok)
System.err.println(<font color=#004488>"EnumWindows failed."</font>);
Thread.currentThread().sleep(3000);
}
}</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The call to <B>sleep( )</B>
allows the windows procedure to complete before <B>main( )</B>
exits.</FONT><A NAME="_Toc408018831"></A><BR></P></DIV>
<A NAME="Heading603"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Other J/Direct features</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There are two more J/Direct
features you can get using modifiers in the <B>@dll.import</B> directive. The
first is simplified access to OLE functions, and the second is the selection of
the ANSI versus Unicode version of API functions. Here is a short description of
the two.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">By convention, all OLE functions
return a value of type HRESULT, which is a structured integer value defined by
COM. If you program at the COM level and you want something different returned
from an OLE function, you must pass it a pointer to a memory area that the
function will fill with data. But in Java we don’t have pointers; also,
this style is not exactly elegant. With J/Direct, you can easily call OLE
functions using the <B>ole</B> modifier in the <B>@dll.import</B> directive. A
native method marked as an <B>ole</B> function is automatically translated from
a Java-style method signature, which is where you decide the return type, into a
COM-style function.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The second feature selects between
ANSI and Unicode string handling. Most Win32 API functions that handle strings
come in two versions. For example, if you look at the symbols exported by the
USER32 DLL, you will not find a <B>MessageBox( )</B> function, but instead
<B>MessageBoxA( )</B> and <B>MessageBoxW( )</B> functions, which are
the ANSI and Unicode version, respectively. If you do not specify which version
you want to call in the <B>@dll.import </B>directive, the JVM will try to figure
it out. But this operation takes some time during program execution time that
you can save with the <B>ansi</B>, <B>unicode,</B> or <B>auto</B>
modifiers.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">For a more detailed discussion of
these features, consult the Microsoft
documentation.</FONT><A NAME="_Toc408018832"></A><BR></P></DIV>
<A NAME="Heading604"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Raw Native Interface (RNI)</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Compared to J/Direct, RNI is a
fairly complex interface to non-Java code, but it’s much more powerful.
RNI is closer to the JVM than J/Direct, and this lets you write much more
efficient code, manipulate Java objects in your native methods, and in general
gives you a much higher degree of integration with the JVM internal
operations.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">RNI is conceptually similar to
Sun’s JNI. Because of this, and because the product is not yet completed,
I’ll just point out the major differences. For further information, please
refer to Microsoft’s documentation.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There are several notable
differences between JNI and RNI. Below is the C header file generated by
<B>msjavah</B>, the Microsoft equivalent of Sun’s <B>javah</B>, applied to
the <B>ShowMsgBox</B> Java class file used previously for the JNI
example.</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>/* DO NOT EDIT -
automatically generated by msjavah */</font>
#include <<font color=#0000ff>native</font>.h>
#pragma warning(disable:4510)
#pragma warning(disable:4512)
#pragma warning(disable:4610)
struct Classjava_lang_String;
#define Hjava_lang_String Classjava_lang_String
<font color=#009900>/* Header for class ShowMsgBox */</font>
#ifndef _Included_ShowMsgBox
#define _Included_ShowMsgBox
#define HShowMsgBox ClassShowMsgBox
typedef struct ClassShowMsgBox {
#include <pshpack4.h>
<font color=#0000ff>long</font> MSReserved;
#include <poppack.h>
} ClassShowMsgBox;
#ifdef __cplusplus
extern <font color=#004488>"C"</font> {
#endif
__declspec(dllexport) <font color=#0000ff>void</font> __cdecl
ShowMsgBox_ShowMessage (struct HShowMsgBox *,
struct Hjava_lang_String *);
#ifdef __cplusplus
}
#endif
#endif <font color=#009900>/* _Included_ShowMsgBox */</font>
#pragma warning(<font color=#0000ff>default</font>:4510)
#pragma warning(<font color=#0000ff>default</font>:4512)
#pragma warning(<font color=#0000ff>default</font>:4610)</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Apart from being less readable,
there are more technical issues disguised in the code, which we’ll
examine.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In RNI, the native method
programmer knows the binary layout of the objects. This allows you to directly
access the information you want; you don’t need to get a field or method
identifier as in JNI. But since not all virtual machines necessarily use the
same binary layout for their objects, the native method above is guaranteed to
run only under the Microsoft JVM.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In JNI, the <B>JNIEnv</B> argument
gives access to a large number of functions to interact with the JVM. In RNI,
the functions for controlling JVM operations are directly available. Some of
them, like the one for handling exceptions, are similar to their JNI
counterparts, but most of the RNI functions have different names and purposes
from those in JNI.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">One of the most remarkable
differences between JNI and RNI is the garbage collection model. In JNI, the GC
basically follows the same rules during native method execution that it follows
for the Java code execution. In RNI, the programmer is responsible for starting
and stopping the Garbage Collector during native method activity. By default,
the GC is disabled upon entering the native method; doing so, the programmer can
assume that the objects being used will not be garbage collected during that
time. But if the native method, let’s say, is going to take a long time,
the programmer is free to enable the GC, calling the <B>GCEnable( )</B> RNI
function.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There is also something similar to
the global handles features – something the programmer can use to be sure
that specific objects will not be garbage collected when the CG is enabled. The
concept is similar but the name is different: in RNI these guys are called
<B>GCFrame</B>s.</FONT><A NAME="_Toc408018833"></A><BR></P></DIV>
<A NAME="Heading605"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
RNI Summary</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The fact that RNI is tightly
integrated with the Microsoft JVM is both its strength and its weakness. RNI is
more complex than JNI, but it also gives you a high degree of control of the
internal activities of the JVM, including garbage collection. Also, it is
clearly designed for speed, adopting compromises and techniques that C
programmers are familiar with. But it’s not suitable for JVMs other than
Microsoft’s.</FONT><A NAME="_Toc408018834"></A><BR></P></DIV>
<A NAME="Heading606"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Java/COM integration</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">COM (formerly known as OLE) is the
Microsoft Component Object Model, the foundation of all ActiveX technologies.
These include ActiveX Controls, Automation, and ActiveX Documents. But COM is
much more; it’s a specification (and a partial implementation) for
developing component objects that can interoperate using dedicated features of
the operating system. In practice, all of the new software developed for Win32
systems has some relationship with COM – the operating system exposes some
of its features via COM objects. Third-party components can be COM, and you can
create and register your own COM components. In one way or another, if you want
to write Win32 code, you’ll have to deal with COM. Here, I’ll just
recap the fundamentals of COM programming, and I’ll assume that you are
familiar with the concept of a COM server (any COM object that can expose
services to COM clients) and a COM client (a COM object that uses the services
provided by a COM server). This section kept things simple; the tools are
actually much more powerful, and you can use them in a more sophisticated way.
But this requires a deep knowledge of COM, which is beyond the scope of this
appendix. If you’re interested in this powerful but platform-dependent
feature, you should investigate COM and the Microsoft documentation on Java/COM
integration. For more information, Dale Rogerson’s “Inside
COM” (Microsoft Press, 1997) is an excellent book.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Since COM is the architectural
heart of all the new Win32 applications, being able to use, or to expose, COM
services from Java code can be important. The Java/COM integration is no doubt
one of the most interesting features of the Microsoft Java compiler and virtual
machine. Java and COM are so similar in their models that the integration is
conceptually straightforward and technically seamless – there’s
almost no special code to write in order to access COM. Most the details are
handled by the compiler and/or by the virtual machine. The effect is that the
COM objects are seen as ordinary Java objects by the Java programmer, and COM
clients can use COM servers implemented in Java just like any other COM server.
Again, I use the generic term COM, but by extension this means that you can
implement an ActiveX Automation server in Java, or you can use an ActiveX
Control in your Java programs.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The most notable similarities
between Java and COM revolve around the relationship between COM interfaces and
the Java <B>interface </B>keyword. This is a near-perfect match
because:</FONT><BR></P></DIV>
<UL>
<LI><FONT FACE="Symbol"> </FONT><FONT FACE="Georgia">A COM object exposes
interfaces (and only
interfaces).</FONT><LI><FONT FACE="Symbol"> </FONT><FONT FACE="Georgia">A
COM interface has no implementation; the COM object exposing an interface is
responsible for its implementation.
</FONT><LI><FONT FACE="Symbol"> </FONT><FONT FACE="Georgia">A COM
interface is a description of a group of functions semantically related; no data
is exposed.</FONT><LI><FONT FACE="Symbol"> </FONT><FONT FACE="Georgia">A
COM class groups together COM interfaces. A Java class can implement an
arbitrary number of Java
interfaces</FONT><LI><FONT FACE="Symbol"> </FONT><FONT FACE="Georgia">COM
has a reference object model; the programmer never “has” an object,
just references to one or more of its interfaces. Java has a reference object
model as well – a reference to an object can be cast to a reference to one
of its
interfaces.</FONT><LI><FONT FACE="Symbol"> </FONT><FONT FACE="Georgia">The
lifetime in memory of a COM object is determined by the number of clients using
the object; when this count goes to zero, the object deletes itself from memory.
In Java, the lifetime of an object is also determined by the number of clients.
When there are no more references to that object, the object is a candidate to
be released by the garbage
collector.</FONT></UL><DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This tight
mapping between Java and COM not only allows the Java programmer to easily
access COM features, but it also makes Java an interesting language for writing
COM code. COM is language-independent, but the de facto languages for COM
development are C++ and Visual Basic. Compared to Java, C++ is much more
powerful for COM development and generates much more efficient code, but
it’s hard to use. Visual Basic is much easier than Java, but it’s
too far from the underlying operating system, and its object model does not map
very well to COM. Java is an excellent compromise between the
two.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Let’s take a look at some of
the keys points of COM development that you need to know to write Java/COM
clients and servers.</FONT><A NAME="_Toc408018835"></A><BR></P></DIV>
<A NAME="Heading607"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
COM Fundamentals <BR><A NAME="Index3094"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">COM is a binary specification for
implementing interoperable objects. For example, COM describes the binary layout
an object should have to be able to call services in another COM object. Since
it’s a description of a binary layout, COM objects can be implemented in
any language that’s able to produce such a layout. Usually the programmer
is freed from these low level details, since the compiler takes care of
gene
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -