PageRenderTime 26ms CodeModel.GetById 23ms app.highlight 0ms RepoModel.GetById 1ms app.codeStats 0ms

/Visual Studio 2008/CppCOMClient/ReadMe.txt

#
Plain Text | 164 lines | 116 code | 48 blank | 0 comment | 0 complexity | 93611829a53dd7d459e9d326cce18f86 MD5 | raw file
  1========================================================================
  2    CONSOLE APPLICATION : CppCOMClient Project Overview
  3========================================================================
  4
  5/////////////////////////////////////////////////////////////////////////////
  6Use:
  7
  8There are three basic ways you can use Automation or consume a COM server in 
  9a native client: MFC, #import, and C/C++.
 10
 111. C/C++
 12
 13The code in RawAPI.h/cpp demontrates the use of C/C++ and the COM APIs to 
 14consume the COM object ATLDllCOMServer.SimpleObject. The raw automation 
 15is much more difficult, but it is sometimes necessary to avoid the overhead
 16with MFC, or problems with #import. Basically, you work with such APIs as 
 17CoCreateInstance(), and COM interfaces such as IDispatch and IUnknown.
 18
 192. #import
 20
 21The code in ImportDirective.h/cpp demonstrates the use of #import to automate
 22a COM server, more specifically, a COM server written in .NET: CSDllCOMServer.
 23#import (http://msdn.microsoft.com/en-us/library/8etzzkb6.aspx), a new  
 24directive that became available with Visual C++ 5.0, creates VC++ "smart 
 25pointers" from a specified type library. It is very powerful, but often not 
 26recommended because of reference-counting problems that typically occur when 
 27used with the Microsoft Office applications. Unlike the direct API approach 
 28in RawAPI.h/cpp, smart pointers enable us to benefit from the type info to 
 29early/late bind the object. #import takes care of adding the messy guids to 
 30the project and the COM APIs are encapsulated in custom classes that the 
 31#import directive generates.
 32
 33The differences between early binding and late binding via smart pointers:
 34
 35Smart pointers make creating an object that supports early binding easy, so
 36does it make creating a late bound object. The only difference between early 
 37binding and late binding via smart pointer is the .tlh and .tli files 
 38generated by the #import directive. If the target object supports early 
 39binding, the .tlh and .tli files will make use of the custom interface (not 
 40IDispatch) to call the target property/method directly. If the target COM 
 41object only support late binding, the smart pointer takes care of converting
 42your method calls into GetIDsOfNames()s and Invoke()s of the IDispatch 
 43interface.
 44
 453. MFC
 46
 47With MFC, Visual C++ ClassWizard can generate "wrapper classes" from the type
 48libraries. These classes simplify the use of the COM servers. Please refer to
 49the sample MFCCOMClient.
 50
 51
 52/////////////////////////////////////////////////////////////////////////////
 53Project Relation:
 54
 55CppCOMClient -> ATLDllCOMServer
 56CppCOMClient is the client application of the COM server ATLDllCOMServer.
 57
 58CppCOMClient -> CSDllCOMServer
 59CppCOMClient is the client application of the COM server CSDllCOMServer.
 60
 61
 62/////////////////////////////////////////////////////////////////////////////
 63Build:
 64
 65CppCOMClient depends on ATLDllCOMServer, CSDllCOMServer. To build and run 
 66CppCOMClient successfully, please make sure ATLDllCOMServer and CSDllCOMServer
 67are built and registered rightly.
 68
 69
 70/////////////////////////////////////////////////////////////////////////////
 71Creation:
 72
 73A. Creating the ATLDllCOMServer.SimpleObject COM object using C++ and  
 74the COM APIs (RawAPI.h/cpp)
 75
 76Step1. Add the automation helper function, AutoWrap.
 77
 78Step2. Initialize COM by calling CoInitializeEx, or CoInitialize.
 79
 80Step3. Get CLSID of the COM server using the API CLSIDFromProgID.
 81
 82Step4. Start the server and get the IDispatch interface using the API 
 83CoCreateInstance.
 84
 85Step5. Consume the COM object with the help of AutoWrap.
 86
 87Step6. Release the COM object
 88
 89Step7. Uninitialize COM for this thread by calling CoUninitialize.
 90
 91B. Creating the CSDllCOMServer.CSExplicitInterfaceObject COM object using the 
 92#import directive and smart pointers (ImportDirecive.h/cpp)
 93
 94Step1. Import the type library of the target COM server using the #import 
 95directive. If the COM object is a .NET component, mscorlib.tlb is also 
 96required to be imported.
 97
 98Step2. Build the project. If the build is successful, the compiler generates 
 99the .tlh and .tli files that encapsulate the COM server based on the type 
100library specified in the #import directive. It serves as a class wrapper we
101can now use to create the COM class and access its properties, methods, etc.
102
103Step3. Create a COM object using the smart pointer. The class name is the 
104original interface name (i.e. ICSExplicitInterfaceObject) with a "Ptr" suffix. 
105We can use either the constructor of the smart pointer class or its 
106CreateInstance method to create the COM object.
107
108Step4. Call the COM object's properties, methods through the smart pointer 
109like this:
110
111	spSimpleObj->FloatProperty = 1.2f;
112
113To access the methods of the smart pointer class itself (e.g. QueryInterface),
114use the dot syntax spSimpleObj.QueryInterface().
115
116Step5. It is necessary to catch the COM errors if the type library was  
117imported without raw_interfaces_only and when the raw interfaces 
118(e.g. raw_HelloWorld) are not used. For example:
119
120	#import "XXXX.tlb"
121	try
122	{
123		_bstr_t result = spSimpleObj->HelloWorld();
124	}
125	catch (_com_error &err)
126	{
127	}
128
129The above code snippet is equivalent to:
130
131	#import "XXXX.tlb"
132	_bstr_t result;
133	HRESULT hr = spSimpleObj->raw_HelloWorld(result.GetAddress());
134	if (FAILED(hr)
135	{
136	}
137
138And it is also the same as:
139
140	#import "XXXX.tlb" raw_interfaces_only
141	_bstr_t result;
142	HRESULT hr = spSimpleObj->HelloWorld(result.GetAddress());
143	if (FAILED(hr)
144	{
145	}
146
147Step6. It is said that the smart pointers are released automatically, so we
148do not need to manually release the COM object.
149
150Step7. Uninitialize COM for this thread by calling CoUninitialize.
151
152
153/////////////////////////////////////////////////////////////////////////////
154References:
155
156COM Programming by Example: Using MFC, ActiveX, ATL, ADO, and COM+ 
157By John E. Swanke
158http://www.amazon.com/COM-Programming-Example-ActiveX-CD-ROM/dp/1929629036
159
160COM Interop Sample: COM Client and .NET Server
161http://msdn.microsoft.com/en-us/library/2w30w8zx.aspx
162
163
164/////////////////////////////////////////////////////////////////////////////