Strange behavior of BSTRs in DCOM
-
Hi Folks ;)) i've got a strange problem with BSTRs in my DCOM application. I'm passing 6 BSTRs in a class object (its properties) to a method on a remote server that has to write these strings in some registry values on a pre-defined key. I've tried both allocating a BSTR and passing it to the server function (see next few lines BSTR bsBuffer; bsBuffer=SysAllocString(OLESTR("Prova")); theApp.m_pHello->SetName(bsBuffer); SysFreeString(bsBuffer); and calling server functions directly passing a string (confiding in the operator= that BSTR involves). theApp.m_pHello->SetDescription("Prova 02/05/2005"); theApp.m_pHello->SetDriver("0.01a"); theApp.m_pHello->SetName("Prova"); theApp.m_pHello->SetVendor("Execute, Crash & Sigh LTD"); theApp.m_pHello->SetLocalBus("VXI"); theApp.m_pHello->SetFirmware("0.00001a"); //Adding Object theApp.m_pHello->Add(); Running application there is no errors, no code violations, no abnormal program terminations, NOTHING.... BUT In the registry I get a strange thing like this (I report values in tabular format) sDesc=Execute, Crash & Sigh LTD sDriver=0.00001a sFirmware=0.00001a sLocalBus=0.00001a sName=0.00001a sVendor=Execute, Crash & Sigh LTD All server functions do nothing but extract the string part in the BSTR and save it in the registry using Windows API functions. What can I do? What can it be? Thanks a lot in advance, Moreno.
-
Hi Folks ;)) i've got a strange problem with BSTRs in my DCOM application. I'm passing 6 BSTRs in a class object (its properties) to a method on a remote server that has to write these strings in some registry values on a pre-defined key. I've tried both allocating a BSTR and passing it to the server function (see next few lines BSTR bsBuffer; bsBuffer=SysAllocString(OLESTR("Prova")); theApp.m_pHello->SetName(bsBuffer); SysFreeString(bsBuffer); and calling server functions directly passing a string (confiding in the operator= that BSTR involves). theApp.m_pHello->SetDescription("Prova 02/05/2005"); theApp.m_pHello->SetDriver("0.01a"); theApp.m_pHello->SetName("Prova"); theApp.m_pHello->SetVendor("Execute, Crash & Sigh LTD"); theApp.m_pHello->SetLocalBus("VXI"); theApp.m_pHello->SetFirmware("0.00001a"); //Adding Object theApp.m_pHello->Add(); Running application there is no errors, no code violations, no abnormal program terminations, NOTHING.... BUT In the registry I get a strange thing like this (I report values in tabular format) sDesc=Execute, Crash & Sigh LTD sDriver=0.00001a sFirmware=0.00001a sLocalBus=0.00001a sName=0.00001a sVendor=Execute, Crash & Sigh LTD All server functions do nothing but extract the string part in the BSTR and save it in the registry using Windows API functions. What can I do? What can it be? Thanks a lot in advance, Moreno.
-
Hi Folks ;)) i've got a strange problem with BSTRs in my DCOM application. I'm passing 6 BSTRs in a class object (its properties) to a method on a remote server that has to write these strings in some registry values on a pre-defined key. I've tried both allocating a BSTR and passing it to the server function (see next few lines BSTR bsBuffer; bsBuffer=SysAllocString(OLESTR("Prova")); theApp.m_pHello->SetName(bsBuffer); SysFreeString(bsBuffer); and calling server functions directly passing a string (confiding in the operator= that BSTR involves). theApp.m_pHello->SetDescription("Prova 02/05/2005"); theApp.m_pHello->SetDriver("0.01a"); theApp.m_pHello->SetName("Prova"); theApp.m_pHello->SetVendor("Execute, Crash & Sigh LTD"); theApp.m_pHello->SetLocalBus("VXI"); theApp.m_pHello->SetFirmware("0.00001a"); //Adding Object theApp.m_pHello->Add(); Running application there is no errors, no code violations, no abnormal program terminations, NOTHING.... BUT In the registry I get a strange thing like this (I report values in tabular format) sDesc=Execute, Crash & Sigh LTD sDriver=0.00001a sFirmware=0.00001a sLocalBus=0.00001a sName=0.00001a sVendor=Execute, Crash & Sigh LTD All server functions do nothing but extract the string part in the BSTR and save it in the registry using Windows API functions. What can I do? What can it be? Thanks a lot in advance, Moreno.
Looks like the theApp.m_pHello object doesn't rightly store the transmitted BSTR strings inside. BSTR strings should be stored by copying of the body, not the pointer.
HRESULT C::SetName(IN BSTR name) { m_nameSaved = name; // It's invalid. Should be m_nameSaved = SysAllocString(name); or other equivalent. } HRESULT C::Add() { // using m_nameSaved as stored string }
With best wishes, Vita -
Looks like the theApp.m_pHello object doesn't rightly store the transmitted BSTR strings inside. BSTR strings should be stored by copying of the body, not the pointer.
HRESULT C::SetName(IN BSTR name) { m_nameSaved = name; // It's invalid. Should be m_nameSaved = SysAllocString(name); or other equivalent. } HRESULT C::Add() { // using m_nameSaved as stored string }
With best wishes, Vita -
OK, I will not free the memory soon, but WHEN can I free that memory? I don't want to make a memory-consuming server...:laugh: Thanx again....
Marshaling layer in COM do free for you in the client side if parameter is [in] type and in server side in [out] parameter. You must free memory (SysfreeString) in client side for [out] parameter,... Try to use _bstr_t type and forget memory alloc and free. Regards...
-
Marshaling layer in COM do free for you in the client side if parameter is [in] type and in server side in [out] parameter. You must free memory (SysfreeString) in client side for [out] parameter,... Try to use _bstr_t type and forget memory alloc and free. Regards...
OK, I tried to follow your tip and went into trouble again (i'm not SO experienced:laugh:). Most of my server Interface's methods use the BSTR type. I tried to change it, but now I need to know how to declare the _bstr_t type in my IDL file. I tried using both import and include (with and without #) WTYPES.H (where _bstr_t is defined) and it seemed not to work (preprocessor error). How to declare it? Another STRAAAAANGE thing is that it fails calling methods that has three int parameters... I know that native C types do not need to be marsaled, am I right? i.e.: theApp.m_pIHello->SetLocation (2,1,0) seems to fail, where function prototype in server side is STDMETHODTYPE CHardwareAsset::SetLocation (int Master, int slot, int SubAssy) I put a statement to log on a file somw phrases just to know where the program goes and what it does, but when I call the method above, the server creates the object, but does NOT log the SetLocation Fu8nction (the logFile statement is the first, just before variable declaration!) Very strange, isn't it? Or it's me that need to return to school and study a lot? :laugh: Thanks again...