This problem seems to be caused by the fact that internally
__VariantChangeType may change the dispatch parameters passed on the Invoke
stack, and this is either not allowed, or is unexpected by the Script
Control. For example, if a component has a LONG (VT_I4) property, and this
property is set by passing it an object (VT_DISPATCH), __VariantChangeType
will perform the type conversion, but in the process will also cause the
reference count of the passed IDispatch interface to be decremented. I
believe the script control is not expecting this, and either does not
correctly AddRef the interface before the Invoke call, or will do a Release
on it afterwards. This problem does not exist in IDispatchImpl<> which does
not change the parameters on the Invoke stack.
To reproduce this problem
Create a simple attributed ATL component that has a single LONG default
(DISPID_VALUE) property. In FinalRelease, get the component to display a
message box to indicate that it is being deleted.
Create a Visual Basic application that uses the Microsoft Script Control.
The script code to be run should set the component default value using the
line "obj=obj". This will cause the default value to be retrieved from obj
and then set using a parameter type of VT_DISPATCH rather than VT_I4. The
script code should be run in response to clicking a command button, after a
few clicks, the component reference count will go to zero and delete its
self after displaying the message box.
Dim obj As New Ctestobject
Private Sub Form_Load()
ScriptControl1.Language = "VBScript"
Dim code As String
code = "sub test()" & vbCrLf & "obj=obj" & vbCrLf & "end sub" & vbCrLf
ScriptControl1.AddCode code
ScriptControl1.AddObject "obj", obj
End Sub
Private Sub Command1_Click()
ScriptControl1.Run "test"
End Sub
I'll try to raise the issue with MS via MVP channels, and let's hope
somebody from MS replies here too. From this point on and until this
issue is resolved, I will recommend staying away from attributed code,
or at least from implementing dual interfaces in attributed code.
--
With best wishes,
Igor Tandetnik
"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken
"David Shepherd" <da...@daveshep.com> wrote in message
news:bf0rdg$rlb$1...@titan.btinternet.com...
> Can confirm.
Please, add also the wrong integral-floating conversion (for example
VT_I4 <-> VT_R8) to the your issue.
I haven't had the time to check this out, but I suppose the behaviour is not
the same with old trustworthy VariantChangeType?
I can't see any good reason whatsoever for the ATL team to implement their
own...? The ATL library is already dependent on OLEAUT32.dll for obvious
reasons, so I see no savings in making a new (buggy) version.
Any thoughts?
--
Best regards,
Kim Gräsman
"Igor Tandetnik" <itand...@mvps.org> wrote in message
news:%23%23kWdNuS...@tk2msftngp13.phx.gbl...
Did so. Numerical conversions are seriously broken. It does not even
convert VT_I2 to VT_I4 properly - negative numbers don't get
sign-extended.
Yes and no. __VariantChangeType attempts to perform "simple" convertions
(numeric to numeric) without calling VariantChangeType, presumably for
optimization, and it does those incorrectly. For all other cases, it
defers to VariantChangeType.
The real issue is this. VariantChangeType gives you a choice between
performing the conversion in-place or preserving the source and putting
the converted data into a separate VARIANT. __VariantChangeType does not
provide this option, it always converts in-place. But
attribute-generated code that calls __VariantChangeType simply passes
pointers straight from DISPPARAMS structure that comes with
IDispatch::Invoke, without making local copies. Thus incoming parameters
are trashed.
> I can't see any good reason whatsoever for the ATL team to implement
their
> own...? The ATL library is already dependent on OLEAUT32.dll for
obvious
> reasons, so I see no savings in making a new (buggy) version.
As I said, the reason probably was an attempt at optimization. They felt
they could convert short to long faster than VariantChangeType. Well,
I'll take slow and correct over fast and buggy any day.
Looks like a premature (read unnecessary) optimization to me...
--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnic...@mvps.org
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================
"Igor Tandetnik" <itand...@mvps.org> wrote in message news:uLT8A35S...@TK2MSFTNGP10.phx.gbl...
Havic
"Igor Tandetnik" <itand...@mvps.org> wrote in message
news:##kWdNuSD...@tk2msftngp13.phx.gbl...
Pretty much. At this time, the attributed implementation of a dual
interface is unusable, can break in unpredictable ways, and is better to
be avoided. The problem is not just with scripts - any client doing
late-bound calls (e.g. VB in late-bound mode) can be broken.
I believe there is a way to use attributes but avoid using attributed
dual interface implementation. Make an attributed coclass as usual, but
derive it from IDispatchImpl as you would in non-attributed code. This
suppresses attributed dual implementation and uses IDispatchImpl
instead. Haven't tried this myself though.
"Igor Tandetnik" <itand...@mvps.org> wrote in message
news:uZTdi85T...@TK2MSFTNGP10.phx.gbl...