|
|
|
date: Sun, 4 Jun 2006 11:15:25 +0200,
group: microsoft.public.platformsdk.com_ole
back
Probable BSTR problem
Hello group i am trying to create a little com client of a COM component
used to get, set, invoke values/method on a hardware RAID card. I believe
the COM component is sucessfully used by a Raid array management utility.
there is no tlb for this client, so i fetched the IDL with oleview and used
MIDL to make the TLB
here is a sample of the IDL for the interface that cause the problem :
the method that causes the problem is get.
hr1 = pft->get(valname,&value);
This cause an access violation. (10008494 mov word ptr [edx],di)
I know there are a lot of tricks with BSTR, but it seems i tried everything
and it doesn't work.
thank you in advance, the IDL and client code follows :
[
odl,
uuid(89176F07-E5EC-11D1-B4A6-00A02448219B),
helpstring("IRiver Interface"),
dual,
oleautomation
]
interface IRiver : IDispatch {
[id(0x00000001), helpstring("method dir")]
HRESULT dir(IUnknown** ppenum);
[id(0x00000002), helpstring("method get")]
HRESULT get(
BSTR name,
BSTR* pValue);
[id(0x00000003), helpstring("method set")]
HRESULT set(
BSTR name,
BSTR value,
unsigned long right);
[id(0x00000004), helpstring("method invoke")]
HRESULT invoke(
BSTR name,
BSTR arg);
[id(0x00000005), helpstring("method refresh")]
HRESULT refresh();
[id(0x00000006), helpstring("method cd")]
HRESULT cd(
BSTR name,
IUnknown** ppriver);
};
Here is my code :
#include <windows.h>
#include <stdio.h>
#import "C:\Program Files\Microsoft Visual
Studio\MyProjects\RaidTest\Debug\ftRAID.tlb"
using namespace I2ORAIDLib;
int main(int argc, char* argv[])
{
CLSID CLSID_ORaid;
IID IID_ORaid;
wchar_t* clsid_str = L"{BCA456A1-D159-11D4-BB07-0050DA2E128F}";
wchar_t* iid_str = L"{89176F07-E5EC-11D1-B4A6-00A02448219B}";
IEnumGUID* pEnumerator;
HRESULT hr
IRiver *pRiver = 0;
IRiver *pft = 0;
IUnknown *pRiver2 = 0;
BSTR controler = L"FTP1";
BSTR valname = L"GetPCIBus";
BSTR value;
ULONG ret;
ULONG celt;
::CLSIDFromString(clsid_str, &CLSID_ORaid);
::IIDFromString(iid_str, &IID_ORaid);
hr = CoInitialize(NULL);
if(SUCCEEDED(hr1))
{
hr1 = CoCreateInstance(CLSID_ORaid, 0, CLSCTX_INPROC_SERVER,
IID_ORaid, (void **) &pRiver);
if(SUCCEEDED(hr1))
{
hr1 = pRiver->cd(controler, &pRiver2);
if(hr1 == 0)
{
hr1 = pRiver2->QueryInterface(IID_ORaid,(void **)
&pft);
pft->AddRef();
hr1 = pft->get(valname,&value);
pft->Release();
}
pRiver->Release();
CoUninitialize();
}
}
return 0;
}
date: Sun, 4 Jun 2006 11:15:25 +0200
author: Rod
Re: Probable BSTR problem
"Rod" wrote in message
news:eIzwrd7hGHA.1864@TK2MSFTNGP02.phx.gbl
> there is no tlb for this client, so i fetched the
> IDL with oleview
Where do you think OleView got the IDL from - thin air? There is a TLB
bound to the DLL as a resource.
> #import "C:\Program Files\Microsoft Visual
> Studio\MyProjects\RaidTest\Debug\ftRAID.tlb"
And here you can simply #import the DLL.
> BSTR controler = L"FTP1";
You can't use a string literal where BSTR is required, even though the
compiler does not complain. A BSTR _must_ be allocated with
SysAllocString, and deallocated with SysFreeString.
> hr1 = pRiver2->QueryInterface(IID_ORaid,(void
> **) &pft);
> pft->AddRef();
QueryInterface returns an AddRef'ed pointer. You don't need to AddRef it
again. Since you effectively AddRef twice but Release only once, you
leak a reference.
> hr1 = pft->get(valname,&value);
Note that get() allocates a BSTR and stores it in 'value'. It is your
responsibility to deallocate this BSTR when you are done with it, using
SysFreeString.
> pRiver->Release();
You forgot to release pRiver2.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
date: Sun, 4 Jun 2006 10:24:24 -0400
author: Igor Tandetnik
|
|