Solved

Different method of accessing ATL COM

Posted on 2004-09-14
7
263 Views
Last Modified: 2013-11-25
Hi,
If you want to use ATL COM in your client application ( VC++ ) Then you can use it through following 2 methods:
1. "Import 'path of dll' " 
2. "include .h and i.c files" right .

there is method with following signature in ATL COM.

GetUserName(out,retval BSTR )


In my client application code will look like this

BSTR bstrUserName= ptrToComServer->GetUserName();

I think till now everything is clear.

Problem is that If I use Import dll (method one) then I can use above line

in case of Include files( method 2 ) I can't use all those methods with above signature.

If my question is not clear pls do tell me so that I can provide some more details.

Can you tell me why I am unable to use [ out,retval ] in case of method 2.
0
Comment
Question by:nkaushik
  • 4
  • 3
7 Comments
 
LVL 9

Accepted Solution

by:
_ys_ earned 200 total points
ID: 12062245
> you can use it through following 2 methods:
There can be considered three, where the third is a hybrid of your two [... details towards the end ...]

> 2. "include .h and i.c files" right .
The actual method signature would have a return type of HRESULT:
HRESULT GetUserName([out,retval] BSTR*)

When using the header method this is all you have. You've oprted to do things the C++ way. You're expected to use this signature and process the HRESULT value - it is useful to know this value, especially upon failure.

> 1. "Import 'path of dll' " 
When you use #import it wraps this method:
inline _bstr_t IComServer::GetUserName ( ) {
    BSTR _result = 0;
    HRESULT _hr = raw_GetUserName(&_result);
    if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
    return _bstr_t(_result, false);
}

All this does is call onto the original signature [HRESULT _hr = raw_GetUserName(&_result);] and processes the HRESULT for you, throwing an exception if warranted.

In other words, it's trying to do things the way VB does it - become an automation client.

> 1. "Import 'path of dll' " 
Do things the automation client way - same as what VB does
> 2. "include .h and i.c files" right .
Do things the C++ way


The way I see it is, you have three choices:

1. use #import the way you currently are.
try {
    BSTR sUserName = pComServer->GetUserName ( );
    SysFreeString(sUserName);
}
catch (_com_error &ex) { ...
}

2. use the header files as you suggested.
HRESULT hr;
BSTR sUserName;
if (SUCCEEDED(hr = pComServer->GetUserName (&sUserName))) {
    SysFreeString(sUserName);
}
else { ...
}

3. use #import with the raw_interfaces_only attribute. [... this is the third way ...]
#import "path to type library" raw_interfaces_only
HRESULT hr;
BSTR sUserName;
if (SUCCEEDED(hr = pComServer->GetUserName (&sUserName))) {
    SysFreeString(sUserName);
}
else { ...
}
0
 

Author Comment

by:nkaushik
ID: 12062570
Hi YS,
       Thanks for your prompt reply it was really nice explanation did't take any time to understand.
My Problem is solved now and code is working fine.
So there is no difference in calling from client(VC++) when we use Method 2 for following 2 signatures

  1. GetUserName([in,out] bstrUserName)
  2. GetUserName([out,retval] bstrUserName)

Calling code for 1 and 2 signature will be:

   HRESULT hr;
  BSTR sUserName;
  if (SUCCEEDED(hr = pComServer->GetUserName (&sUserName))) {
     SysFreeString(sUserName);
     }



So there is a difference in calling from client(VC++) when we use Method 1 for following 2 signatures

  1. GetUserName([in,out] bstrUserName)
  2. GetUserName([out,retval] bstrUserName)

  Calling code for signature 1 and 2 will be :
    1. Calling code will be same like above
     2. BSTR bstrUserName=pComServer->GetUserName()


 Keep it Up!!!!
 
   

0
 
LVL 9

Expert Comment

by:_ys_
ID: 12062656
> So there is no difference in calling from client(VC++) when we use Method 2 for following 2 signatures
>  1. GetUserName([in,out] bstrUserName)
>  2. GetUserName([out,retval] bstrUserName)

Sorry, but there is a difference here ... apart from the obvious signature ...

The difference is due to memory management. By specifying a BSTR parameter as [in] you're telling the COM server that memory has already been allocated.

1. GetUserName([in,out] bstrUserName)
HRESULT hr;
BSTR sUserName = SysAllocString(L""); // [in] is specified so we need to allocate memory
if (SUCCEEDED(hr = pComServer->GetUserName (&sUserName))) {
    SysFreeString(sUserName);
}

Note that the COM server uses SysReAllocString (or SysFreeString / SysAllocString) if neceessary.

2. GetUserName([out,retval] bstrUserName)
HRESULT hr;
BSTR sUserName; // no need to allocate memory as [in] not specified. Indeed soing so would cause a memory leak
if (SUCCEEDED(hr = pComServer->GetUserName (&sUserName))) {
    SysFreeString(sUserName);
}

Note that the COM server uses SysAllocString.

And just for completeness sake:
3. GetUserName([in] bstrUserName)
HRESULT hr;
BSTR sUserName = SysAllocString(L""); // [in] is specified so we need to allocate memory
if (SUCCEEDED(hr = pComServer->GetUserName (&sUserName))) {
    SysFreeString(sUserName);
}

Note that the COM server doesn't allocate or deallocate memory. In fact reallocation should not be performed either. The COM server should treat this as read-only.


In all scenarios, the COM client must invoke SysFreeString when complete, else a memory leak results.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:nkaushik
ID: 12062690
Your are right Mr. YS there is difference internally but what I meant is there is no difference in calling convention( means signature from client app).
0
 
LVL 9

Expert Comment

by:_ys_
ID: 12062901
That's right, both are invoked the same way.

if (SUCCEEDED(hr = pComServer->GetUserName (&sUserName))) {
    SysFreeString(sUserName);
}
0
 

Author Comment

by:nkaushik
ID: 12063108
by the way where are you from and on which technology or technologies you are working ??
0
 
LVL 9

Expert Comment

by:_ys_
ID: 12063369
I've updated my member profile with a few details for all to read.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
fix34  challenge 9 104
Sed question 2 68
Post a good COM tutorial 1 49
Best book to learn C++ 4 70
With most software applications trying to cater to multiple user needs nowadays, the focus is to make them as configurable as possible. For e.g., when creating Silverlight applications which will connect to WCF services, the service end point usuall…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now