📄 tij0195.html
字号:
<html><body>
<table width="100%"><tr>
<td>
<a href="http://www.bruceeckel.com/javabook.html">Bruce Eckel's Thinking in Java</a>
</td>
<td align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0194.html">Prev</a> | <a href="tij0196.html">Next</a>
</td>
</tr></table>
<hr>
<H2 ALIGN=LEFT>
Java/COM
integration
</H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">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><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">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><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
most notable similarities between Java and COM revolve around the relationship
between COM interfaces and the Java
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">keyword.
This is a near-perfect match because:
</FONT><P></DIV>
<UL>
<LI><FONT FACE="Symbol" SIZE=3 COLOR="Black"> </FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">A
COM object exposes interfaces (and only interfaces).
</FONT><LI><FONT FACE="Symbol" SIZE=3 COLOR="Black"> </FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">A
COM interface has no implementation; the COM object exposing an interface is
responsible for its implementation.
</FONT><LI><FONT FACE="Symbol" SIZE=3 COLOR="Black"> </FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">A
COM interface is a description of a group of functions semantically related; no
data is exposed.
</FONT><LI><FONT FACE="Symbol" SIZE=3 COLOR="Black"> </FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">A
COM class groups together COM interfaces. A Java class can implement an
arbitrary number of Java interfaces
</FONT><LI><FONT FACE="Symbol" SIZE=3 COLOR="Black"> </FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">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" SIZE=3 COLOR="Black"> </FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">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><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">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><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">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><P></DIV>
<A NAME="Heading608"></A><H3 ALIGN=LEFT>
COM
Fundamentals
<P><A NAME="Index3106"></A></H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">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 generating the correct layout. For
example, if you program in C++, most compilers generate a virtual function
table that is COM-compliant. With languages that do not produce executable
code, such as VB and Java, the runtime takes care of hooking into COM.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
COM Library also supplies a few basic functions, such as the ones for creating
an object or locating a COM class registered in your system.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
main goals of a component object model are:
</FONT><P></DIV>
<UL>
<LI><FONT FACE="Symbol" SIZE=3 COLOR="Black"> </FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Let
objects call services into other objects.
</FONT><LI><FONT FACE="Symbol" SIZE=3 COLOR="Black"> </FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Allow
new types of objects, or upgrades to existing ones, to be seamlessly plugged
into the environment.
</FONT></UL><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
first point is exactly what object-oriented programming is about: you have a
client object that makes requests to a server object. In this case, the terms
“client” and “server” are used in a generic way, and
not to refer to some particular hardware configuration. With any
object-oriented language, the first goal is easy to achieve if your application
is a monolithic piece of code that implements both the server object code and
the client object code. If you make changes to the way client and the server
objects interface with each other, you simply compile and link again. When you
restart your application, it uses a new version of the components.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
situation is completely different when your application is made up of component
objects that are not under your control – you don’t control their
source code and they can evolve separately from your application. This is
exactly the case, for example, when you use a third-party ActiveX Control in
your application. The control is installed in your system, and your application
is able, at runtime, to locate the server code, activate the object, link to
it, and use it. Later, you can install a newer version of the control, and your
application should still be able to run; in the worst case, it should
gracefully report an error condition, such as “Control not found,”
without hanging up.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
these scenarios, your components are implemented in separate executable code
files: DLLs or EXEs. If the server object is implemented in a separate
executable code file, you need a standard, operating system supplied method to
activate these objects. Of course, in your code you do not want to use the
physical name and location of the DLL or EXE, because these might change; you
want some identifier maintained by the operating system. Also, your application
needs a description of the services exposed by the server. This is exactly what
I’ll cover in the next two sections.
</FONT><P></DIV>
<A NAME="Heading609"></A><H4 ALIGN=LEFT>
GUIDs
and the Registry
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">COM
uses structured integer numbers, 128 bits long, to unequivocally identify COM
entities registered in the system. These numbers, called <A NAME="Index3107"></A>GUIDs
(Globally Unique IDentifiers) can be generated by specific utilities, and are
guaranteed to be unique “in space and in time,” to quote Kraig
Brockschmidt. In space, because the number is generator reads the id of your
network card, and in time because the system date and time are used as well. A
GUID can be used to identify a COM class (in which case it’s called a
CLSID) or a COM interface (IID). The names are different but the concept and
the binary structure are the same. GUIDs are also used in other situations that
I will not cover here.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">GUIDs,
along with their associated information, are stored in the <A NAME="Index3108"></A><A NAME="Index3109"></A>Windows
Registry, or Registration Database. It’s a hierarchical database, built
into the operating system, which holds a great amount of information about the
hardware and software configuration of your system. For COM, the Registry keeps
track of the components installed in your system, such as their CLSIDs, the
name and location of the executable file that implement them, and a lot of
other details. One of these details is the ProgID of the component; a ProgID is
conceptually similar to a GUID in the sense that it identifies a COM component.
The difference is that a GUID is a binary, algorithmically-generated value,
whereas a <A NAME="Index3110"></A>ProgID
is a programmer-defined string value. A ProgID is associated with a <A NAME="Index3111"></A>CLSID.</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">A
COM component is said to be registered in the system when at least its CLSID
and its executable file location are present in the Registry (the ProgID is
usually present as well). Registering and using COM components is exactly what
we’ll do in the following examples.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">One
of the effects of the Registry is as a decoupling layer between the client and
server objects. The client activates the server using some information that is
stored in the Registry; one piece of information is the physical location of
the server executables. If the location changes, the information in the
Registry is updated accordingly, but this is transparent to the client, which
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -