Wednesday, December 3, 2008

The Class Definition


Our object uses a default constructor. You can add special initialization here if required, but there are some limitations. One consequence of

using the ATL_NO_VTABLE is that you aren not allowed to call any virtual methods in the constructor. A better place for complex initialization

would be in the FinalConstruct method (which is inherited from CComObjectRootEx.) If you want to use FinalConstruct, override ATL's default

by declaring it in the class definition. It will be called automatically by the ATL framework. (FinalConstruct is often used to create aggregated

objects.)

The DECLARE_REGISTRY_RESOURCEID() macro is used to register the COM object in the system registry. The parameter to this macro,

IDR_BEEPOBJ, points to a resource in the project. This is a special kind of resource that loads the MIDL-generated ".rgs" file.

BEGIN_COM_MAP is a macro that defines an array of COM interfaces that the CComObjectRoot< > class will manage. This class has one

interface, IBeepObj. IBeepObj is our custom interface. It is common for COM objects to implement more than one interface. All supported

interfaces would show up here, as well as in the class inheritance at the top of the class definition.

The Method

At last, we get to the methods. As an application programmer, our main interest will be in this section of the code. Our single Beep() method is

defined in the line:

STDMETHOD(Beep)(/*[in]*/ LONG duration);

STDMETHOD is an OLE macro that translates to the following:

typedef LONG HRESULT;

#define STDMETHODCALLTYPE __stdcall

#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method

We could have written the definition in a more familiar C++ style as follows:

virtual long _stdcall Beep(long lDuration);

We'll find the code for this method in the BeepObj.cpp module. Because this COM object has only one method, the COM object's source code is

pretty sparse. All the COM logic of the object was defined in the ATL template classes. We're left with just the actual application code. When

you are writing real applications, most of your attention will be focused on this module.

STDMETHODIMP Beep(long lDuration)

{

http://devcentral.iticentral.com/articles/DCOM/intro_DCOM/part2/3.php (4 of 6) [7/9/2001 2:52:53 PM]

DevCentral - Understanding DCOM - Part II

::Beep( 660, lDuration );

return S_OK;

}

Again, the function definition translates into a standard function call.

long _stdcall CBeepObj::Beep( long lDuration )

The API beep routine takes two parameters: the frequency of the beep, and it's duration in milliseconds. If you're working with Windows 95,

these two parameters are ignored and you get the default beep. The scope operator "::" is important, but is easily forgotten. If you neglect it,

the method will be calling itself.

The _stdcall tag tells the compiler that the object uses standard windows calling conventions. By default C and C++ use the __cdecl calling

convention. These directives tell the compiler which order it will use for placing parameters on, and removing them from, the stack. Win32

COM uses the _stdcall atribute. Other operating systems may use different calling conventions.

Notice that our Beep() method returns a status of S_OK. This doesn't mean that the caller will always get a successful return status.

Remember that calls to COM methods aren't like standard C++ function calls. There is an entire COM layer between the calling program

(client) and the COM server.

It is entirely possible that the CBeepObj::Beep() method would return S_OK, but the connection would be lost in the middle of a COM call.

Although the function would return S_OK, the calling client would get some sort of RPC error indicating the failure. Even the function result has

to be sent through COM back to the client!

In this example the COM server is running as an In-Process server. Being a DLL, the linkage is so tight there is very little chance of

transmission error. In future examples, where our COM server is running on a remote computer, things will be very different. Network errors

are all too common, and you need to design your applications to handle them.

Server Registration

0 comments: