Using BSTR in COM Exe server 
Author Message
 Using BSTR in COM Exe server

Hi all

I am facing some problems when passing the BSTR parameters
as the in parameter to the ATL COM EXE server.

I am using ATL 3.0 on WinNT platform.The scenario is as
follows.

Following is the idl file entries for the GetCfgString
method.

id(1), helpstring("method GetCfgString")] HRESULT
GetCfgString([in]BSTR bstrSection,[in]BSTR bstrKey,[out]
BSTR*  bstrVal,

[in,defaultvalue("C:\\hmi\\init\\config.ini")] BSTR
bstrFileName);

my COM server crashes when i am calling the GetCfgString  
after the 5th or 6th time.

Following is the way i pass the parameter to the above
method.

//code
CComBSTR bstrCurrentConfig;
BSTR bstrRet;

bstrCurrentConfig =  "Page1"

hr = pFileObj->GetCfgString(bstrCurrentConfig,A2BSTR
("HVMaster"),&bstrRet,A2BSTR
("C:\\hmi\\init\\config1.ini"));

//end code

1) do you think there is any problem in converting the
character array to BSTR as A2BSTR(..) ?.

or is it possible for me to pass second parameter as the
following

hr = pFileObj->GetCfgString(bstrCurrentConfig,CComBSTR
("HVMaster"),&bstrRet,CComBSTR
("C:\\hmi\\init\\config1.ini"));
out of this which of them is the better or i have to adopt
some other method?

2) the second problem is when ever i don't pass the fourth
parameter, ATL is not replacing the
default parameter i specified in the idl file in to the
bstrFileName, is there any problem in specifying
the default parameter the way i had done here?.

The above code was working perfectly with out crashing
until i add the last default parameter, so i am
confused as is there any thing wrong in the method i had
chosen.

the implementation of the GetCfgString is as follows

STDMETHODIMP CFileObj::GetCfgString(BSTR bstrSection, BSTR
bstrKey, BSTR *bstrVal,BSTR bstrFileName)
{
        char chrVal[500];
        HRESULT hr = S_OK;

        USES_CONVERSION;

        GetPrivateProfileString(OLE2A(bstrSection),OLE2A
(bstrKey),"file_reading_error", chrVal,500,OLE2A
(bstrFileName));
    if (_stricmp( chrVal, "file_reading_error") == 0)
        {
        hr = MAKE_HRESULT
(SEVERITY_ERROR,FACILITY_ITF,E_KEYNAME_NOTFOUND_IN_CONFIGFI
LE);
            return  Error(ERROR_3,IID_IFileObj,hr);
        }
    else
        {
        *bstrVal = A2BSTR(chrVal);
         return S_OK;
        }

Quote:
}

should i allocate memory for the fourth parameter bstrVal
in the GetCfgString method using
SysAllocString() API in the server side?? if so, whose
responsiblity should be to release the
memory allocated??.

Waiting for your early advices.

Karinta.(BMA)



Mon, 07 Jun 2004 16:22:07 GMT  
 Using BSTR in COM Exe server
The defaultvalue attribute is just a hint that compilers can optionally
support.  VC ignores it, so you still have to supply the parameter.  There
are some problems with memory leakage in your sample, and I can't tell from
the sample if the interface point is being properly disposed.  One way you
could call this method would be like this:

CComPtr<IFileObjInterfaceName> obj;
< code to create class and assign to smart pointer>

CComBSTR bstrRet;

HRESULT hr = obj->GetCfgString(CComBSTR(L"Page1"), CComBSTR(L"HVMaster"),
&bstrRet, CComBSTR(L"C:\\hmi\\init\\config1.ini"));

<do something with bstrRet>

Using the wrapper classes will cause the interface pointer and BSTRs to be
cleaned up properly.  And prefixing your string constants with L will
prevent the need to convert from ANSI to wide character strings.

---------------------------------------------------------
Automate your software builds with Visual Build
http://www.kinook.com


Quote:
> Hi all

> I am facing some problems when passing the BSTR parameters
> as the in parameter to the ATL COM EXE server.

> I am using ATL 3.0 on WinNT platform.The scenario is as
> follows.

> Following is the idl file entries for the GetCfgString
> method.

> id(1), helpstring("method GetCfgString")] HRESULT
> GetCfgString([in]BSTR bstrSection,[in]BSTR bstrKey,[out]
> BSTR*  bstrVal,

> [in,defaultvalue("C:\\hmi\\init\\config.ini")] BSTR
> bstrFileName);

> my COM server crashes when i am calling the GetCfgString
> after the 5th or 6th time.

> Following is the way i pass the parameter to the above
> method.

> file://code
> CComBSTR bstrCurrentConfig;
> BSTR bstrRet;

> bstrCurrentConfig =  "Page1"

> hr = pFileObj->GetCfgString(bstrCurrentConfig,A2BSTR
> ("HVMaster"),&bstrRet,A2BSTR
> ("C:\\hmi\\init\\config1.ini"));

> file://end code

> 1) do you think there is any problem in converting the
> character array to BSTR as A2BSTR(..) ?.

> or is it possible for me to pass second parameter as the
> following

> hr = pFileObj->GetCfgString(bstrCurrentConfig,CComBSTR
> ("HVMaster"),&bstrRet,CComBSTR
> ("C:\\hmi\\init\\config1.ini"));
> out of this which of them is the better or i have to adopt
> some other method?

> 2) the second problem is when ever i don't pass the fourth
> parameter, ATL is not replacing the
> default parameter i specified in the idl file in to the
> bstrFileName, is there any problem in specifying
> the default parameter the way i had done here?.

> The above code was working perfectly with out crashing
> until i add the last default parameter, so i am
> confused as is there any thing wrong in the method i had
> chosen.

> the implementation of the GetCfgString is as follows

> STDMETHODIMP CFileObj::GetCfgString(BSTR bstrSection, BSTR
> bstrKey, BSTR *bstrVal,BSTR bstrFileName)
> {
> char chrVal[500];
> HRESULT hr = S_OK;

> USES_CONVERSION;

> GetPrivateProfileString(OLE2A(bstrSection),OLE2A
> (bstrKey),"file_reading_error", chrVal,500,OLE2A
> (bstrFileName));
>     if (_stricmp( chrVal, "file_reading_error") == 0)
> {
>         hr = MAKE_HRESULT
> (SEVERITY_ERROR,FACILITY_ITF,E_KEYNAME_NOTFOUND_IN_CONFIGFI
> LE);
>     return  Error(ERROR_3,IID_IFileObj,hr);
> }
>     else
> {
>      *bstrVal = A2BSTR(chrVal);
>          return S_OK;
> }
> }

> should i allocate memory for the fourth parameter bstrVal
> in the GetCfgString method using
> SysAllocString() API in the server side?? if so, whose
> responsiblity should be to release the
> memory allocated??.

> Waiting for your early advices.

> Karinta.(BMA)



Mon, 07 Jun 2004 22:30:17 GMT  
 Using BSTR in COM Exe server
Looks like you got some good advice from the previous reply.  In general,
though, I would suggest using CComBSTR so as to free the consumer of your
strings from the burden of having to free the memory allocated for the
string (which is also done automatically for you if you use the CComBSTR).
Yes, if you use pure BSTRs, then the provider will have to use
SysAllocString() and that memory will have to be freed somewhere (client or
server / provider or consumer) - probably best to let the consumer of the
string free that memory when done with it.

You may want to be watchful to ensure that your BSTR's aren't being assigned
null strings, or at least know if they are.  I recently saw some very
strange behavior:  my client was requesting 4 BSTRs from the server in a
method call (as [out] parameters, obviously).  Everything was fine until one
of the BSTRs (CComBSTR) was assigned a null string.  As I traced the method
call I could see the server assigning BSTRs 1, 2 and 3 to some expected
data.  BSTR 4 received a null string.  However, what arrived back in the
client was completely unexpected - BSTR 4 received the same string as BSTR 2
while BSTRs 1 and 3 were null!

More comments inline below:

Russ


Quote:
> Hi all

> I am facing some problems when passing the BSTR parameters
> as the in parameter to the ATL COM EXE server.

> I am using ATL 3.0 on WinNT platform.The scenario is as
> follows.

> Following is the idl file entries for the GetCfgString
> method.

> id(1), helpstring("method GetCfgString")] HRESULT
> GetCfgString([in]BSTR bstrSection,[in]BSTR bstrKey,[out]
> BSTR*  bstrVal,

> [in,defaultvalue("C:\\hmi\\init\\config.ini")] BSTR
> bstrFileName);

> my COM server crashes when i am calling the GetCfgString
> after the 5th or 6th time.

> Following is the way i pass the parameter to the above
> method.

> //code
> CComBSTR bstrCurrentConfig;
> BSTR bstrRet;

> bstrCurrentConfig =  "Page1"

> hr = pFileObj->GetCfgString(bstrCurrentConfig,A2BSTR
> ("HVMaster"),&bstrRet,A2BSTR
> ("C:\\hmi\\init\\config1.ini"));

Who's deallocating the BSTRs being created in the above method call?  I
think this may be the memory leak Kyle alluded to previously.

Quote:
> //end code

> 1) do you think there is any problem in converting the
> character array to BSTR as A2BSTR(..) ?.

> or is it possible for me to pass second parameter as the
> following

> hr = pFileObj->GetCfgString(bstrCurrentConfig,CComBSTR
> ("HVMaster"),&bstrRet,CComBSTR
> ("C:\\hmi\\init\\config1.ini"));
> out of this which of them is the better or i have to adopt
> some other method?

For the reasons described above I would suggest using CComBSTR.  Also, I
guess I would tend to do the string constructions outside of the COM method
call.  For me it's easier to debug.  In your situation I would also make use
of member variables to hold your Key and Filename BSTRs, as follows:

// in client class definition
CComBSTR  m_bstrKey;
CComBSTR  m_bstrFilename;

// in client class constructor
m_bstrKey = "HVMaster";
m_bstrFilename = "C:\\hmi\\init\\config1.ini";

// in client method call
hr = pFileObj->GetCfgString(bstrCurrentConfig,
                                             m_bstrKey,
                                             &bstrRet,
                                             m_bstrFilename);

- Show quoted text -

Quote:
> 2) the second problem is when ever i don't pass the fourth
> parameter, ATL is not replacing the
> default parameter i specified in the idl file in to the
> bstrFileName, is there any problem in specifying
> the default parameter the way i had done here?.

> The above code was working perfectly with out crashing
> until i add the last default parameter, so i am
> confused as is there any thing wrong in the method i had
> chosen.

> the implementation of the GetCfgString is as follows

> STDMETHODIMP CFileObj::GetCfgString(BSTR bstrSection, BSTR
> bstrKey, BSTR *bstrVal,BSTR bstrFileName)
> {
> char chrVal[500];
> HRESULT hr = S_OK;

> USES_CONVERSION;

> GetPrivateProfileString(OLE2A(bstrSection),OLE2A
> (bstrKey),"file_reading_error", chrVal,500,OLE2A
> (bstrFileName));
>     if (_stricmp( chrVal, "file_reading_error") == 0)
> {
>         hr = MAKE_HRESULT
> (SEVERITY_ERROR,FACILITY_ITF,E_KEYNAME_NOTFOUND_IN_CONFIGFI
> LE);
>     return  Error(ERROR_3,IID_IFileObj,hr);
> }
>     else
> {
>      *bstrVal = A2BSTR(chrVal);
>          return S_OK;
> }
> }

> should i allocate memory for the fourth parameter bstrVal
> in the GetCfgString method using
> SysAllocString() API in the server side?? if so, whose
> responsiblity should be to release the
> memory allocated??.

> Waiting for your early advices.

> Karinta.(BMA)



Fri, 11 Jun 2004 14:16:03 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. Lifetime of EXE COM server that uses DLL COM server

2. Using one COM exe server within another

3. Problems using a ATL COM EXE Server with VB Client

4. How to pass BSTR to out of process COM server

5. Using, in CE, _bstr_t (the BSTR COM encapsulation)

6. Using, in CE, _bstr_t (the BSTR COM encapsulation)

7. EXE COM Server Possible in C#?

8. Serialize access to COM exe Server (long)

9. COM servers in EXE

10. COM EXE Server - please make me sane

11. COM EXE Server Registration?

12. COM exe server

 

 
Powered by phpBB® Forum Software