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

📄 ch12.htm

📁 用VC开发activeX控件的电子书,很不错的
💻 HTM
📖 第 1 页 / 共 5 页
字号:
	is standard OLE return value. If the return value is <I>not</I> an <TT>HRESULT</TT>,
	the MIDL compiler will not provide marshaling information to marshal across process
	boundaries. The return value <TT>HRESULT</TT> is needed for network support. In case
	a network error occurs, a valid error code can be returned without having to generate
	an exception.

</BLOCKQUOTE>

<P><IMG SRC="bar.gif" WIDTH="480" HEIGHT="6" ALIGN="BOTTOM" BORDER="0"><BR>
<BR>
The interface for <TT>IBASS</TT> is shown in Listing 12.2. Note that <TT>IBass</TT>
is an aggregate interface, <I>not</I> an inherited interface. Aggregate interfaces
will be explained in the section &quot;Implementing the Interface.&quot;
<H3><A NAME="Heading13"></A>Listing 12.2<SPACER TYPE="HORIZONTAL" SIZE="10"> IBASS.IDL--Interface
Definition for IBass</H3>
<P><FONT COLOR="#0066FF"><TT>[ <BR>
object, <BR>
uuid(F60D7C40-5B4E-11d0-ABE6-D07900C10000), <BR>
pointer_default(unique) <BR>
] <BR>
interface IBass : IUnknown <BR>
{ <BR>
import &quot;unknwn.idl&quot;; <BR>
HRESULT GetLocation([out, string, size_is(255)] char *p); <BR>
HRESULT SetLocation([in, string] char *p); <BR>
HRESULT EatsOtherFish([out] BOOL *pBool); } </TT></FONT></P>
<H3><A NAME="Heading14"></A>Compiling the Interface Definition Files</H3>
<P>After the respective IDL files have been created, they must be compiled in order
for the interface code to be generated. Since the MIDL compiler was added to the
project in the section &quot;Adding the MIDL Compiler to the IDE,&quot; this task
is an easy one.</P>
<P>To compile the IDL files, perform the following steps:

<OL>
	<LI>Load the file IFish.IDL into the Visual C++ environment.
	<P>
	<LI>Select the command Compile <U>I</U>DL from the <U>T</U>ools menu in the Visual
	C++ development environment.
	<P>
	<LI>Load the file IBass.IDL into the Visual C++ environment.
	<P>
	<LI>Select the command Compile <U>I</U>DL from the <U>T</U>ools menu in the Visual
	C++ development environment.
	<P>
	<LI>The MIDL compiler has now compiled the interface definition files and generated
	the source code for supporting these interfaces.
</OL>

<P>You may be surprised to see the code that is generated by the MIDL compiler from
the simple interface definitions <TT>IFish</TT> and <TT>IBass</TT>. Unlike a C++
compiler, the output from MIDL is <I>not</I> binary code. Instead, MIDL generates
C code, which is then compiled by the C compiler as part of the interface project.</P>
<P>When the file IFISH.IDL was compiled, the files shown in Table 12.2 were generated.

<TABLE BORDER="1" WIDTH="100%">
	<CAPTION><B>Table 12.2</B><SPACER TYPE="HORIZONTAL" SIZE="10"><B> Results Produced by Compiling
		IFISH.IDL</B></CAPTION>
	<TR ALIGN="LEFT" rowspan="1">
		<TD ALIGN="LEFT" VALIGN="TOP"><B>File</B></TD>
		<TD ALIGN="LEFT" VALIGN="TOP"><B>Purpose</B></TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD ALIGN="LEFT" VALIGN="TOP">IFISH.H</TD>
		<TD ALIGN="LEFT" VALIGN="TOP">Support header file for the <TT>IFish</TT> interface.</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD ALIGN="LEFT" VALIGN="TOP">IFISH_I.C</TD>
		<TD ALIGN="LEFT" VALIGN="TOP">Interface definition file that is added to both the server and client projects.</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD ALIGN="LEFT" VALIGN="TOP">IFISH_P.C</TD>
		<TD ALIGN="LEFT" VALIGN="TOP">Proxy code that implements the marshaling code for the interface.</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD ALIGN="LEFT" VALIGN="TOP">DLLDATA.C</TD>
		<TD ALIGN="LEFT" VALIGN="TOP">Reference file used for loading the correct interface from the DLL. Shared by all
			IDL files compiled within this project.</TD>
	</TR>
</TABLE>
<BR>
<BR>
The files that were created by the MIDL compiler must now be added to the IFISH project.
<BR>
<BR>
<IMG SRC="bar.gif" WIDTH="480" HEIGHT="6" ALIGN="BOTTOM" BORDER="0"></P>


<BLOCKQUOTE>
	<P><B>NOTE:</B> When the IFISH project was created, no source files were included
	in the project. The entire project consisted of only a MAK file. Since this is an
	interface-only DLL, the entire contents of the project will consist of the files
	created via the MIDL compiler.

</BLOCKQUOTE>

<P><IMG SRC="bar.gif" WIDTH="480" HEIGHT="6" ALIGN="BOTTOM" BORDER="0"><BR>
<BR>
The following files must be added to the IFISH makefile in order for the <TT>IFish</TT>
and <TT>IBass</TT> interface definitions to be accessible and used in COM Object
implementations. 
<TABLE BORDER="0">
	<TR ALIGN="LEFT" rowspan="1">
		<TD ALIGN="LEFT">ifish.h</TD>
		<TD ALIGN="LEFT">ibass_i.c</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD ALIGN="LEFT">ifish_i.c</TD>
		<TD ALIGN="LEFT">ibass_p.c</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD ALIGN="LEFT">ifish_p.c</TD>
		<TD ALIGN="LEFT">Dlldata.c</TD>
	</TR>
	<TR ALIGN="LEFT" rowspan="1">
		<TD ALIGN="LEFT">ibass.h</TD>
		<TD ALIGN="LEFT">Rpchelp.c</TD>
	</TR>
</TABLE>
You can add these files to the project by performing the following steps:

<OL>
	<LI>From the Visual C++ development environment, select the <U>F</U>iles command
	from the <U>A</U>dd to Project menu item, which can be accessed from the <U>F</U>ile
	menu. The Insert Files into Project dialog is displayed (see fig. 12.6).
	<P><A HREF="Art/12/ifig06.jpg"><B>FIG. 12.6</B></A> <I><BR>
	The Insert Files into Project dialog is used for adding MIDL files into a project.</I></P>
	<LI>Select the files shown in the preceding file list, and click OK. The files are
	now added to the interface project make file.
</OL>

<H3><A NAME="Heading15"></A>Creating a Definition File</H3>
<P>One of the tedious tasks that, unfortunately, is not performed by either the Application
Wizard or the MIDL compiler is the creation of a library definition file (DEF). This
library definition file, a standard part of DLLs, defines which functions are exported
or made accessible by the DLL. The filename is IFISH.DEF. <BR>
<BR>
<IMG SRC="bar.gif" WIDTH="480" HEIGHT="6" ALIGN="BOTTOM" BORDER="0"></P>


<BLOCKQUOTE>
	<P><B>NOTE:</B> Since a standard Win32 DLL was created, there were no functions to
	be exported because there were no source files when the file was created. This is
	<I>not</I> the case when an MFC DLL is created. In that case, MFC source code is
	produced, and a DEF file for the project is also created with default functions exported
	through the DEF file.

</BLOCKQUOTE>

<P><IMG SRC="bar.gif" WIDTH="480" HEIGHT="6" ALIGN="BOTTOM" BORDER="0"><BR>
<BR>
The contents of the IFISH.DEF file were created manually and can be viewed in Listing
12.3.
<H3><A NAME="Heading16"></A>Listing 12.3<SPACER TYPE="HORIZONTAL" SIZE="10"> DLL
LIBRARY--Definition File for IFISH.DLL</H3>
<P><FONT COLOR="#0066FF"><TT>LIBRARY IFISH <BR>
DESCRIPTION `IFISH Interface Marshaling' <BR>
EXPORTS <BR>
DllGetClassObject <BR>
DllCanUnloadNow </TT></FONT></P>
<P>The DLL entry points <I>must</I> be defined because of the parameter-marshaling
code generated by the MIDL compiler. The MIDL compiler generates code that uses the
<TT>IMarshall</TT> interface. The <TT>IMarshall</TT> interface requires the DLL entry
point's <TT>DllGetClassObject</TT><B> </B>and <TT>DllCanUnloadNow</TT>. The <TT>IMarshall</TT>
interface is a COM interface that implements parameter marshaling for all COM Objects.</P>
<P>These two entry points are explained in greater detail in the section &quot;Accessing
In-Process COM Objects.&quot;
<H3><A NAME="Heading17"></A>Adding the RPC Libraries to the Interface Project</H3>
<P>Parameter marshaling is implemented through RPC (Remote Procedure Calls) libraries.
When creating interface libraries that use RPC for parameter marshaling, you must
link a number of RPC libraries into the interface project. You can select from two
methods for linking the RPC libraries into the interface project:

<UL>
	<LI>Add the library names to the list of input libraries used when linking the project.
	<LI>Create a file with compiler pragmas that reference the libraries.
</UL>

<P>Four RPC libraries must be included in the interface project, rpcndr.lib, rpcdce4.lib,
rpcns4.lib, and rpcrt4.lib. Creating a file with compiler pragmas is much easier
than trying to remember these library filenames and including them for each project
that defines a COM interface.</P>
<P>In the IFISH project is a file called RPCHELP.C (see Listing 12.4). This file
contains the necessary compiler pragmas for RPC support.
<H3><A NAME="Heading18"></A>Listing 12.4<SPACER TYPE="HORIZONTAL" SIZE="10">RPCHELP.C--Compiler
Pragmas Used for Referencing RPC Libraries</H3>
<P><FONT COLOR="#0066FF"><TT>#pragma comment(lib, &quot;rpcndr.lib&quot;) <BR>
#pragma comment(lib, &quot;rpcns4.lib&quot;) <BR>
#pragma comment(lib, &quot;rpcrt4.lib&quot;) </TT></FONT></P>
<P>The file RPCHELP.C must be added to the IFISH project in order for the project
to link properly. The file can be added to the project by performing the following
steps:

<OL>
	<LI>From the Visual C++ development environment, select the <U>F</U>iles command
	from the <U>A</U>dd to Project menu item, which can be accessed from the <U>F</U>ile
	menu.
	<P>
	<LI>Select the files shown in the file list provided earlier in this chapter, and
	click OK. The files are now added to the interface project make file.
</OL>

<P>The interface definitions for IFISH are now complete, and the project is ready
to be built. Building the project generates a DLL called IFISH.DLL.
<H3><A NAME="Heading19"></A>Registering the Interfaces</H3>
<P>Only one task remains before the <TT>IFish</TT> and <TT>IBass</TT> interfaces
can be used. The interfaces must be registered in the Windows registry. The Windows
registry is the holding ground for all class and interface IDs.</P>
<P>For the IFISH project, a registration file named IFISH.REG must be manually created.
The contents of IFISH.REG are shown in code Listing 12.5.
<H3><A NAME="Heading20"></A>Listing 12.5 <SPACER TYPE="HORIZONTAL" SIZE="10">IFISH.REG--Contexts
of IFISH.REG File Used to Register the Interfaces Supported by the IFISH.DLL</H3>
<P><FONT COLOR="#0066FF"><TT>HKEY_CLASSES_ROOT\Interface\{011BB310-5AB0-11d0-907E-00A0C91FDE82}
<BR>
HKEY_CLASSES_ROOT\Interface\{011BB310-5AB0-11d0-907E-00A0C91FDE82} \ProxyStubClsid32
<BR>
HKEY_CLASSES_ROOT\CLSID\{011BB310-5AB0-11d0-907E-00A0C91FDE82} = IFish_PSFactory
<BR>
HKEY_CLASSES_ROOT\CLSID\{011BB310-5AB0-11d0-907E-00A0C91FDE82}\InprocServer32 = d:\dev\ifish\debug\ifish.dll
<BR>
HKEY_CLASSES_ROOT\Interface\{F60D7C40-5B4E-11d0-ABE6-D07900C10000} <BR>
HKEY_CLASSES_ROOT\Interface\{F60D7C40-5B4E-11d0-ABE6-D07900C10000} \ProxyStubClsid32
<BR>
HKEY_CLASSES_ROOT\CLSID\{F60D7C40-5B4E-11d0-ABE6-D07900C10000} = IBass_PSFactory
<BR>
HKEY_CLASSES_ROOT\CLSID\{F60D7C40-5B4E-11d0-ABE6-D07900C10000}\InprocServer32 = d:\dev\ifish\debug\ifish.dll
</TT></FONT></P>
<P>To add the interface keys to the Windows registry, do the following:

<OL>
	<LI>Select the command <U>R</U>egistry Editor from the <U>T</U>ools menu of the Visual
	C++ development environment.
	<P>
	<LI>Select the command <U>I</U>mport Registry File from the Registry Editor <U>F</U>ile
	menu.
	<P>
	<LI>Select the file IFISH.REG, and then select OK.
</OL>

<H2><A NAME="Heading21"></A>Implementing the Interface</H2>
<P>Now that the <TT>IFish</TT> interface definitions are defined, the object that
implements the interfaces must be created. Remember that the <TT>IFISH</TT> interface
DLL contains <I>only</I> the interface definitions and RPC proxy code for parameter
marshaling. There is no code for implementing the interface within IFISH.DLL. The
COM Object developed in this section in the project BASS.DLL will contain an MFC
class called <TT>CBass</TT> that will implement both the <TT>IFish</TT> and <TT>IBass</TT>
interfaces.</P>
<P>COM Objects can be implemented as either a DLL or an EXE. COM Objects that reside
within a DLL are called in-process servers. COM Objects that reside in an EXE are
called out-of-process servers. The application that will use the COM Objects does
not see a difference between the two types of servers. However, internally, there

⌨️ 快捷键说明

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