Invalid Procedure Call or Argument when testing my ATL Collection object in VB...
Author |
Message |
J. Dudgeo #1 / 5
|
 Invalid Procedure Call or Argument when testing my ATL Collection object in VB...
Hey guys. I've tried to figure this out on my own but I'm stumped. I've written a inproc server with ATL and attempted to implement a collection object. Here is the IDL (this is a snippet, there are other interface/coclass defs): [ object, uuid(FE933A1D-8DE0-4098-8D27-49D64BFA2622), dual, helpstring("ITGLStrings Interface"), pointer_default(unique), oleautomation ] interface ITGLStrings : IDispatch { [propget, id(0), helpstring("method Item")] HRESULT Item([in, out] VARIANT* index, [out, retval] VARIANT* pItem); [propget, id(1), helpstring("property Count")] HRESULT Count([out, retval] long *pVal); [id(2), helpstring("method Add")] HRESULT Add([in] BSTR pName, [in] BSTR pData, [in] BSTR pMediaFilename, [out, retval] ITGLString** pString ); [id(3), helpstring("method Remove")] HRESULT Remove([in, out] VARIANT* index); [propget, id(DISPID_NEWENUM), helpstring("property _NewEnum"), restricted] HRESULT _NewEnum([out, retval] IUnknown** pVal); }; The weird part is this: When I test the component in Visual Basic, if I using the TGLString.Item property this way: TGLStrings.Item("somekey") It works fine. If I pass an numeric value to the Item property: TGLStrings.Item(1) I get a "Runtime Error 5, Invalid Procedure Call or Argument." Now here is the kicker - when I compile the VB test project to an executable and run it, TGLStrings.Item(1) works! It only doesn't work in when running the code under the VB IDE. If I create the component in VB and use VB's Collection class, it works fine. I even tried copying the TGLStrings IDL interface definition, produced by VB, into the my ATL project but with no luck. What am I missing? Thank you in advance, Joel
|
Wed, 08 Sep 2004 10:11:35 GMT |
|
 |
Alexander Nickolo #2 / 5
|
 Invalid Procedure Call or Argument when testing my ATL Collection object in VB...
Check your code handling the Item index VARIANT. Perhaps you reject some valid vartype? (VT_I2 vs VT_I4 comes to mind...) -- ===================================== Alexander Nickolov Microsoft MVP [VC], MCSD
MVP VC FAQ: http://www.mvps.org/vcfaq ===================================== Quote:
> Hey guys. > I've tried to figure this out on my own but I'm stumped. > I've written a inproc server with ATL and attempted to implement a > collection object. > Here is the IDL (this is a snippet, there are other interface/coclass defs): > [ > object, > uuid(FE933A1D-8DE0-4098-8D27-49D64BFA2622), > dual, > helpstring("ITGLStrings Interface"), > pointer_default(unique), > oleautomation > ] > interface ITGLStrings : IDispatch > { > [propget, id(0), helpstring("method Item")] HRESULT Item([in, out] > VARIANT* index, [out, retval] VARIANT* pItem); > [propget, id(1), helpstring("property Count")] HRESULT Count([out, retval] > long *pVal); > [id(2), helpstring("method Add")] HRESULT Add([in] BSTR pName, [in] BSTR > pData, [in] BSTR pMediaFilename, [out, retval] ITGLString** pString ); > [id(3), helpstring("method Remove")] HRESULT Remove([in, out] VARIANT* > index); > [propget, id(DISPID_NEWENUM), helpstring("property _NewEnum"), restricted] > HRESULT _NewEnum([out, retval] IUnknown** pVal); > }; > The weird part is this: > When I test the component in Visual Basic, if I using the TGLString.Item > property this way: > TGLStrings.Item("somekey") > It works fine. If I pass an numeric value to the Item property: > TGLStrings.Item(1) > I get a "Runtime Error 5, Invalid Procedure Call or Argument." Now here is > the kicker - when I compile the VB test project to an executable and run it, > TGLStrings.Item(1) works! It only doesn't work in when running the code > under the VB IDE. > If I create the component in VB and use VB's Collection class, it works > fine. I even tried copying the TGLStrings IDL interface definition, > produced by VB, into the my ATL project but with no luck. > What am I missing? > Thank you in advance, > Joel
|
Wed, 08 Sep 2004 10:32:40 GMT |
|
 |
J. Dudgeo #3 / 5
|
 Invalid Procedure Call or Argument when testing my ATL Collection object in VB...
No I test for VT_I2 and VT_I4... Well I made a discovery: ------------------------- If I do this: TGLStrings.Add "some name" TGLStrings.Item 1 TGLStrings.Remove 1 Everything works fine. If I do this: TGLStrings.Add "some name" For Each Item In TGLStrings ' do something Next TGLStrings.Item 1 ' or TGLStrings.Remove 1 The Item and Remove methods generate errors. The strange part is that if I pass a string to those methods: TGLStrings.Item "some name" TGLStrings.Remove "some name" It works! It also works if I compiled the VB tester into an EXE. Go figure. What I'm wondering is if there is an issue in my get__NewEnum method... Since Item and Remove only fail in the VB IDE *after* the call to For Each ... In ... (which calls _NewEnum.) This is going to drive me nuts... So any other ideas? Thanks for the help. BTW Here is my get_NewEnum code (I know it isn't efficient...) STDMETHODIMP CTGLStrings::get__NewEnum(IUnknown** pVal) { int size = collection_.GetSize(); VARIANT* pVar = new VARIANT[size]; for(int idx = 0; idx < size; ++idx) { pVar[idx].vt = VT_DISPATCH; pVar[idx].pdispVal = collection_.GetValueAt(idx); } typedef CComObject<CComEnum<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, _Copy<VARIANT> > > enumVar; enumVar* pEnumVar = new enumVar; pEnumVar->Init(&pVar[0], &pVar[size], NULL, AtlFlagCopy); delete pVar; return pEnumVar->QueryInterface(IID_IUnknown, (void**)pVal); Quote: }
Check your code handling the Item index VARIANT. Perhaps you reject some valid vartype? (VT_I2 vs VT_I4 comes to mind...) -- ===================================== Alexander Nickolov Microsoft MVP [VC], MCSD
MVP VC FAQ: http://www.mvps.org/vcfaq =====================================
Quote: > Hey guys.
<snip>
|
Wed, 08 Sep 2004 11:39:26 GMT |
|
 |
J. Dudgeo #4 / 5
|
 Invalid Procedure Call or Argument when testing my ATL Collection object in VB...
Another update. OK. It appears that the bug has to do with the data parameter being passed to the Item and Remove methods. Get this, if I don't call For Each ... In on the object when the Item/Remove methods are called, the VARIANT parameter, index.lVal is equal to 1. If I call For Each ... In on the object before calling Item/Remove when one of those methods are called the value of index.lVal is equal to 1835009. What is strange is that this parameter is an incoming parameter. Doesn't the client allocate the memory for this parameter? So how is it being corrupted? As I said, everything works when I compile the VB test program. The error only occurs after calling For Each ... In before Item/Remove and *only* while in the VB IDE/debug mode. Argh. Any ideas? Thanks, Joel
Quote: > No I test for VT_I2 and VT_I4... > Well I made a discovery: > ------------------------- > If I do this: > TGLStrings.Add "some name" > TGLStrings.Item 1 > TGLStrings.Remove 1 > Everything works fine. > If I do this: > TGLStrings.Add "some name" > For Each Item In TGLStrings > ' do something > Next > TGLStrings.Item 1 > ' or > TGLStrings.Remove 1 > The Item and Remove methods generate errors. > The strange part is that if I pass a string to those methods: > TGLStrings.Item "some name" > TGLStrings.Remove "some name" > It works! > It also works if I compiled the VB tester into an EXE. Go figure. > What I'm wondering is if there is an issue in my get__NewEnum method... > Since Item and Remove only fail in the VB IDE *after* the call to For Each > ... In ... (which calls _NewEnum.) This is going to drive me nuts... > So any other ideas? > Thanks for the help. > BTW Here is my get_NewEnum code (I know it isn't efficient...) > STDMETHODIMP CTGLStrings::get__NewEnum(IUnknown** pVal) > { > int size = collection_.GetSize(); > VARIANT* pVar = new VARIANT[size]; > for(int idx = 0; idx < size; ++idx) > { > pVar[idx].vt = VT_DISPATCH; > pVar[idx].pdispVal = collection_.GetValueAt(idx); > } > typedef CComObject<CComEnum<IEnumVARIANT, &IID_IEnumVARIANT, > VARIANT, > _Copy<VARIANT> > > enumVar; > enumVar* pEnumVar = new enumVar; > pEnumVar->Init(&pVar[0], &pVar[size], NULL, AtlFlagCopy); > delete pVar; > return pEnumVar->QueryInterface(IID_IUnknown, (void**)pVal); > }
> Check your code handling the Item index VARIANT. Perhaps you reject some > valid vartype? (VT_I2 vs VT_I4 comes to mind...) > -- > ===================================== > Alexander Nickolov > Microsoft MVP [VC], MCSD
> MVP VC FAQ: http://www.mvps.org/vcfaq > =====================================
> > Hey guys. > <snip>
|
Wed, 08 Sep 2004 12:07:15 GMT |
|
 |
Craig Power #5 / 5
|
 Invalid Procedure Call or Argument when testing my ATL Collection object in VB...
Quote:
> OK. It appears that the bug has to do with the data parameter being passed > to the Item and Remove methods. > Get this, if I don't call For Each ... In on the object when the Item/Remove > methods are called, the VARIANT parameter, index.lVal is equal to 1. If I > call For Each ... In on the object before calling Item/Remove when one of > those methods are called the value of index.lVal is equal to 1835009. What > is strange is that this parameter is an incoming parameter. Doesn't the > client allocate the memory for this parameter? So how is it being > corrupted? > As I said, everything works when I compile the VB test program. The error > only occurs after calling For Each ... In before Item/Remove and *only* > while in the VB IDE/debug mode. Argh. > Any ideas?
Have you tried debugging in VC yet? Debug...Go from the ATL project, using VB6.exe as the executable for the session.
|
Fri, 10 Sep 2004 23:11:35 GMT |
|
|
|