• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 300
  • Last Modified:

Different method of accessing ATL COM

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
nkaushik
Asked:
nkaushik
  • 4
  • 3
1 Solution
 
_ys_Commented:
> 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
 
nkaushikAuthor Commented:
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
 
_ys_Commented:
> 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
nkaushikAuthor Commented:
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
 
_ys_Commented:
That's right, both are invoked the same way.

if (SUCCEEDED(hr = pComServer->GetUserName (&sUserName))) {
    SysFreeString(sUserName);
}
0
 
nkaushikAuthor Commented:
by the way where are you from and on which technology or technologies you are working ??
0
 
_ys_Commented:
I've updated my member profile with a few details for all to read.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now