Yet another SAFEARRAY problem...
Author |
Message |
Aaron Elber #1 / 8
|
 Yet another SAFEARRAY problem...
Hello all! I'm having trouble returning a SAFEARRAY of VARIANTs, and I suspect the problem is with the ATL macros that define the array. Its like this: in idl file: HRESULT RV( [in] ULONG dwCount, [out, retval] VARIANT* pValues); in server side: SAFEARRAY * pRetSA; pRetSA = SafeArrayCreate(VT_VARIANT, 2, bounds); ... SafeArrayPutElement(pRetSA, arr, &varData); ... VariantClear(pValues); V_VT(pValues) = VT_ARRAY | VT_VARIANT; V_ARRAY(pValues) = pRetSA; and in client: VARIANT pVariant; pVariant.vt = VT_BYREF | VT_VARIANT; hr = pIMME->RV(n, &pVariant); When I execute this, the server side receives the variant as VT_EMPTY, ans as this it returns it, with error "Invalid access to memory location". What am I doing wrong? Thanks in advance, Aaron
|
Thu, 26 Sep 2002 03:00:00 GMT |
|
 |
Adrian Edmond #2 / 8
|
 Yet another SAFEARRAY problem...
I found that the IDL definition needed to be something like: ...,SAFEARRAY(unsigned char) myData,... and the SAFEARRAY should have been created client side. Adrian Edmonds
Quote: > Hello all! > I'm having trouble returning a SAFEARRAY of VARIANTs, and I suspect the > problem is with the ATL macros that define the array. Its like this: > in idl file: > HRESULT RV( [in] ULONG dwCount, [out, retval] VARIANT* pValues); > in server side: > SAFEARRAY * pRetSA; > pRetSA = SafeArrayCreate(VT_VARIANT, 2, bounds); > ... > SafeArrayPutElement(pRetSA, arr, &varData); > ... > VariantClear(pValues); > V_VT(pValues) = VT_ARRAY | VT_VARIANT; > V_ARRAY(pValues) = pRetSA; > and in client: > VARIANT pVariant; > pVariant.vt = VT_BYREF | VT_VARIANT; > hr = pIMME->RV(n, &pVariant); > When I execute this, the server side receives the variant as VT_EMPTY, ans > as this it returns it, with error "Invalid access to memory location". What > am I doing wrong? > Thanks in advance, > Aaron
|
Fri, 27 Sep 2002 03:00:00 GMT |
|
 |
Aaron Elber #3 / 8
|
 Yet another SAFEARRAY problem...
The parameter is a VARIANT holding a safearray of variants. This variant is indeed created at client side. Aaron
Quote: > I found that the IDL definition needed to be something like: > ...,SAFEARRAY(unsigned char) myData,... > and the SAFEARRAY should have been created client side. > Adrian Edmonds
> > Hello all! > > I'm having trouble returning a SAFEARRAY of VARIANTs, and I suspect > the > > problem is with the ATL macros that define the array. Its like this: > > in idl file: > > HRESULT RV( [in] ULONG dwCount, [out, retval] VARIANT* pValues); > > in server side: > > SAFEARRAY * pRetSA; > > pRetSA = SafeArrayCreate(VT_VARIANT, 2, bounds); > > ... > > SafeArrayPutElement(pRetSA, arr, &varData); > > ... > > VariantClear(pValues); > > V_VT(pValues) = VT_ARRAY | VT_VARIANT; > > V_ARRAY(pValues) = pRetSA; > > and in client: > > VARIANT pVariant; > > pVariant.vt = VT_BYREF | VT_VARIANT; > > hr = pIMME->RV(n, &pVariant); > > When I execute this, the server side receives the variant as VT_EMPTY, ans > > as this it returns it, with error "Invalid access to memory location". > What > > am I doing wrong? > > Thanks in advance, > > Aaron
|
Fri, 27 Sep 2002 03:00:00 GMT |
|
 |
Alexander Nickolo #4 / 8
|
 Yet another SAFEARRAY problem...
If you want to pass the array from the client to the server, use [in] instead. If you want to pass the array in, modify it there and return it back, use [in, out]. With [out] (same as [out, retval]) you don't get anything from the client. -- ===================================== Alexander Nickolov Microsoft MVP [VC], MCSD
MVP VC FAQ: http://www.mvps.org/vcfaq =====================================
Quote: > Hello all! > I'm having trouble returning a SAFEARRAY of VARIANTs, and I suspect the > problem is with the ATL macros that define the array. Its like this: > in idl file: > HRESULT RV( [in] ULONG dwCount, [out, retval] VARIANT* pValues); > in server side: > SAFEARRAY * pRetSA; > pRetSA = SafeArrayCreate(VT_VARIANT, 2, bounds); > ... > SafeArrayPutElement(pRetSA, arr, &varData); > ... > VariantClear(pValues); > V_VT(pValues) = VT_ARRAY | VT_VARIANT; > V_ARRAY(pValues) = pRetSA; > and in client: > VARIANT pVariant; > pVariant.vt = VT_BYREF | VT_VARIANT; > hr = pIMME->RV(n, &pVariant); > When I execute this, the server side receives the variant as VT_EMPTY, ans > as this it returns it, with error "Invalid access to memory location". What > am I doing wrong? > Thanks in advance, > Aaron
|
Fri, 27 Sep 2002 03:00:00 GMT |
|
 |
Aaron Elber #5 / 8
|
 Yet another SAFEARRAY problem...
Mmm..., let me ask a general question first: if a method is defined as xxx([out] LONG* pLong), then this is a LONG storage passed by the client to the server for it to put whatever it wants in and send it back, right? So why can't I pass a VARIANT* as [out, retval], pointing to an empty variant created by the client, for the server to fill it with a safearray of something and return it back? What I'm missing here? However, I set the method I need to be [in,out], but now I get back at the client an error "The memory is locked". Is the code I posted for the client/server correct, or something is missing? Should I create an empty safearray at client side and then the server should fill it, or it should be created by the server and released by the client? Thanks! Aaron
Quote: > If you want to pass the array from the client to the server, use [in] > instead. If you want to pass the array in, modify it there and return > it back, use [in, out]. With [out] (same as [out, retval]) you don't > get anything from the client. > -- > ===================================== > Alexander Nickolov > Microsoft MVP [VC], MCSD
> MVP VC FAQ: http://www.mvps.org/vcfaq > =====================================
> > Hello all! > > I'm having trouble returning a SAFEARRAY of VARIANTs, and I suspect > the > > problem is with the ATL macros that define the array. Its like this: > > in idl file: > > HRESULT RV( [in] ULONG dwCount, [out, retval] VARIANT* pValues); > > in server side: > > SAFEARRAY * pRetSA; > > pRetSA = SafeArrayCreate(VT_VARIANT, 2, bounds); > > ... > > SafeArrayPutElement(pRetSA, arr, &varData); > > ... > > VariantClear(pValues); > > V_VT(pValues) = VT_ARRAY | VT_VARIANT; > > V_ARRAY(pValues) = pRetSA; > > and in client: > > VARIANT pVariant; > > pVariant.vt = VT_BYREF | VT_VARIANT; > > hr = pIMME->RV(n, &pVariant); > > When I execute this, the server side receives the variant as VT_EMPTY, ans > > as this it returns it, with error "Invalid access to memory location". > What > > am I doing wrong? > > Thanks in advance, > > Aaron
|
Sat, 28 Sep 2002 03:00:00 GMT |
|
 |
Lawrence Grove #6 / 8
|
 Yet another SAFEARRAY problem...
Quote: > Mmm..., let me ask a general question first: if a method is defined as > xxx([out] LONG* pLong), then this is a LONG storage passed by the client to > the server for it to put whatever it wants in and send it back, right? So > why can't I pass a VARIANT* as [out, retval], pointing to an empty variant > created by the client, for the server to fill it with a safearray of > something and return it back? What I'm missing here? > However, I set the method I need to be [in,out], but now I get back at the > client an error "The memory is locked". Is the code I posted for the > client/server correct, or something is missing? Should I create an empty > safearray at client side and then the server should fill it, or it should be > created by the server and released by the client?
I think what Alexander was trying to say is this: [in] client allocates storage and is responsible for release aswell [out] server allocates, client releases. [in, out] as [in]. However, if the server wants to change what was passed in it can by releasing (maybe after a copy) the original and then allocating something new (which in all cases the client must release). I think this is right!! HTH, Loz.
|
Sat, 28 Sep 2002 03:00:00 GMT |
|
 |
Aaron Elber #7 / 8
|
 Yet another SAFEARRAY problem...
Ok, that means that if I want the server to return to the client a variant containing a safearray of variants then the client must allocate them before calling the server? But the client doesn't know how many elements will be in the safearray. Is enough to send an empty safearray? Can somebody post a few lines of code doing this (or fix the original ones I posted)? Thanks! Aaron
Quote: > I think what Alexander was trying to say is this: > [in] client allocates storage and is responsible for release aswell > [out] server allocates, client releases. > [in, out] as [in]. However, if the server wants to change what was > passed in it can by releasing (maybe after a copy) the original and then > allocating something new (which in all cases the client must release). > I think this is right!! > HTH, Loz.
|
Sat, 28 Sep 2002 03:00:00 GMT |
|
 |
Alexander Nickolo #8 / 8
|
 Yet another SAFEARRAY problem...
Replace your VariantClear with VariantInit - that was what I spotted in your code. Also, pass an empty VARIANT from the client, because else you get a memory leak at the client... -- ===================================== Alexander Nickolov Microsoft MVP [VC], MCSD
MVP VC FAQ: http://www.mvps.org/vcfaq =====================================
Quote: > Ok, that means that if I want the server to return to the client a variant > containing a safearray of variants then the client must allocate them before > calling the server? But the client doesn't know how many elements will be in > the safearray. Is enough to send an empty safearray? Can somebody post a few > lines of code doing this (or fix the original ones I posted)? > Thanks! > Aaron
> > I think what Alexander was trying to say is this: > > [in] client allocates storage and is responsible for release aswell > > [out] server allocates, client releases. > > [in, out] as [in]. However, if the server wants to change what was > > passed in it can by releasing (maybe after a copy) the original and then > > allocating something new (which in all cases the client must release). > > I think this is right!! > > HTH, Loz.
|
Sat, 28 Sep 2002 03:00:00 GMT |
|
|
|