1. IntroductionI was new to COM/DCOM programming when I started learning this "old-fashioned" technology a month ago. I found it was very hard to find helpful tutorials on the Internet. I did find some tutorials out there, but I felt that they were not good resources to learn from because they were either "too old" or too hard to re-generate the claimed results. These resources were mostly developed under Visual Studio 6, they generally focused on some in-depth technical details of COM/DCOM and were not written for absolute beginners. This tutorial has three goals: firstly, developing COM/DCOM server/client under the latest development environment; secondly, making the implementation as simple as possible; thirdly, providing elaborate description on the procedure of the implementation. 2. The Simplest Chat ServerThis tutorial will create a simple COM-based chat server and a console application will consume the service provided by the server. The server is the simplest one I have ever implemented because:
Collapse | Copy Code SimplestMethod(client_send_something_to_server, server_send_something_to_client)
The Server takes four steps to implement. 2.1 Creating ATL ProjectA simple shell is created to hold COM object via "ATL project" wizard. To start the wizard, please follow the steps: click the "File" menu, choose the "New" -> "Project..." menu item. The "New Project" window will show as follows. We choose "ATL Project", input the solution name as " Nothing needs to be changed for the wizard, so we simply click "Finish" button and let our server code be generated on the fly. Although we don't care about the details under the hood, there are several things worth being mentioned here.
2.2 Adding COM Class to ServerA COM class is a class inherited from a COM interfaces. A COM interface is a struct (there is no difference between struct and class in Visual C++) inherited from To add a new COM class to the server, open the "Class View" of the project just created, right click the " At the "New Class" wizard below, we choose "ATL" -> "ATL simple object" and click "Add" button. The "ATL Simple Object" wizard is displayed as below: We simply type " To continue the wizard, we click the "Next>" button and the "Options" window will show up. We simply set the options of the "ATL object" to the most commonly used ones as shown in the picture below. There are four categories for the options and each category worth a whole chapter to explain. As this tutorial is intended for beginners, what I can tell you at the moment is to click the "Finish" button at the following screen and close the wizard. 2.3 Adding Method to InterfaceIn the class view of the project, expanding the " The new method is named " The first parameter " 2.4 Coding MethodIn the class view window below, choose the COM class " At the SimpleChatServer.cpp file, the final Collapse | Copy Code STDMETHODIMP CSimpleChatServer::CallMe(BSTR name, BSTR** helloMessage)
{
// TODO: Add your implementation code here
CString temp = _T("Hi ");
temp += name;
temp += ", welcome to the simple chat server!";
BSTR str = temp.AllocSysString();
*helloMessage = &str;
return S_OK;
}
2.5 Compiling the ServerThe compilation of the server is as simple as pressing "F7" or choosing "Build" menu and clicking "Build Solution" menuitem. Visual Studio 2008 will compile the server and register the COM class and interface with the operating system. Consequently, we can find corresponding entries and 3. The Simplest ClientWe'll add the client project at the solution within which we created the server project. To do this, please open "Solution Explorer" and right click the solution " We add a new Win32 Console Application called " The new Win32 console application is fairly straightforward. The simplest client takes seven steps. Its code is fully documented, so I simply put the code here. Collapse | Copy Code /*
** This client shows the procedure of creating the simplest COM client.
** This client is a CONSOLE application and uses IN-PROCESS COM server.
** The server serves ONLY one client.
** Two-way communication is achieved in a synchronous manner by passing
** pointer to server so that server can pass something back to client.
*/
#include "stdafx.h"
/*
** STEP 1
** including two files created by the server
** these files contain the information about ATL object and interfaces
** such as CLASSID and INTERFACEID.
*/
#include "../SimpleCOM/SimpleCOM_i.h"
#include "../SimpleCOM/SimpleCOM_i.c"
int _tmain(int argc, _TCHAR* argv[])
{
BSTR* message; //used to accept return value from server.
HRESULT hr; //COM error code;
ISimpleChatServer *chat; //pointer to the interface
/*
** STEP 2
** Initialize COM and check for success
*/
hr = CoInitialize(0);
if(SUCCEEDED(hr))
{
/*
** STEP 3
** Create an instance of the COM server object.
** The most important result of this function call
** is that we get a pointer to the server interface.
** The function takes 5 parameters
** param #1: class ID of server COM class
** param #2: outer interface(used in aggregation)
** param #3: class context.
** param #4: interface ID.
** param #5: pointer to the interface of interest.
*/
hr = CoCreateInstance(
CLSID_SimpleChatServer,
NULL,
CLSCTX_INPROC_SERVER,
IID_ISimpleChatServer,
(void**) &chat);
if(SUCCEEDED(hr))
{
/*
** STEP 4
** call method via Interface ID.
*/
hr = chat -> CallMe(_T("Zhiwei"), &message);
MessageBox(NULL,*message, _T("Message returned from chat server"),0);
/*
** STEP 5
** de-allocation of BSTR to prevent memory leak
** string handling is big topic in COM
*/
::SysFreeString(*message);
/*
** STEP 6
** Decrease server's object reference counter.
** this is a important step and has been done at client side,
** so that server knows that it can de-allocate an object.
*/
hr = chat -> Release();
}
}
/*
** STEP 7
** close COM.
*/
CoUninitialize();
return 0;
}
Finally, you need to set the " |
|