15.02.2015 Views

C# 4 and .NET 4

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Using a .neT Component from a CoM Client ❘ 719<br />

#import "./DotNetComponent/bin/debug/DotnetServer.tlb" named_guids<br />

using namespace std;<br />

using namespace DotnetComponent;<br />

code snippet COMClient/COMClient.cpp<br />

In the _tmain() method, the fi rst thing to do before any other COM call is the initialization of COM<br />

with the API call CoInitialize() . CoInitialize() creates <strong>and</strong> enters an STA for the thread. The<br />

variable spWelcome is of type IWelcomePtr , which is a smart pointer. The smart pointer method<br />

CreateInstance() accepts the ProgID as an argument to create the COM object by using the COM API<br />

CoCreateInstance() . The operator - > is overridden with the smart pointer, so that you can invoke the<br />

methods of the COM object such as Greeting() :<br />

int _tmain(int argc, _TCHAR* argv[])<br />

{<br />

HRESULT hr;<br />

hr = CoInitialize(NULL);<br />

try<br />

{<br />

IWelcomePtr spWelcome;<br />

// CoCreateInstance()<br />

hr = spWelcome.CreateInstance("Wrox.DotnetComponent");<br />

cout < < spWelcome- > Greeting("Bill") < < endl;<br />

The second interface supported by your .<strong>NET</strong> component is IMath , <strong>and</strong> there is also a smart pointer<br />

that wraps the COM interface: IMathPtr . You can directly assign one smart pointer to another as in<br />

spMath = spWelcome; . In the implementation of the smart pointer (the = operator is overridden), the<br />

QueryInterface() method is called. With a reference to the IMath interface, you can call the Add() method.<br />

IMathPtr spMath;<br />

spMath = spWelcome; // QueryInterface()<br />

long result = spMath- > Add(4, 5);<br />

cout < < "result:" < < result < < endl;<br />

}<br />

If an HRESULT error value is returned by the COM object (this is done by the CCW that returns HRESULT<br />

errors if the .<strong>NET</strong> component generates exceptions), the smart pointer wraps the HRESULT errors <strong>and</strong><br />

generates _com_error exceptions instead. Errors are h<strong>and</strong>led in the catch block. At the end of the<br />

program, the COM DLLs are closed <strong>and</strong> unloaded using CoUninitialize() :<br />

catch (_com_error & e)<br />

{<br />

cout < < e.ErrorMessage() < < endl;<br />

}<br />

CoUninitialize();<br />

return 0;<br />

}<br />

Now you can run the application, <strong>and</strong> you will get outputs from the Greeting() <strong>and</strong> the Add() methods<br />

to the console. You can also try to debug into the smart pointer class, where you can see the COM API<br />

calls directly.<br />

If you get an exception stating that the component cannot be found, check if the<br />

same version of the assembly that is confi gured in the registry is installed in the global<br />

assembly cache.<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!