Solved

Different method of accessing ATL COM

Posted on 2004-09-14
7
262 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
Comment Utility
> 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
Comment Utility
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_
Comment Utility
> 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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:nkaushik
Comment Utility
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_
Comment Utility
That's right, both are invoked the same way.

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

Author Comment

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

Expert Comment

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

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
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…

743 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

17 Experts available now in Live!

Get 1:1 Help Now