I have a program which references a number of ActiveX controls through
VBScript using the Microsoft Script Control. This setup has been working
fine for a long time now, but just lately when I start to use attributed ATL
controls within the project, things have started to go horribly wrong.
Since I am successfully using many different types of ActiveX controls
within this project, I decided to do some tests, and created two identical
controls, one which used attributed ATL and one that does not, the
attributed version caused my program to crash while the other version worked
fine. After searching around a bit for information I tried replacing the
injected IDispatch implementation of the attributed control with the normal
IDispatchImpl<> base class and this made the control work without a problem.
Can anyone know What is going on here? Is there a bug in the injected
IDispatch? Right now I am trying to debug this myself also, but if anyone
else has similar problem maybe can help.
TIA
> Can anyone know What is going on here? Is there a bug in the injected
> IDispatch? Right now I am trying to debug this myself also, but if anyone
> else has similar problem maybe can help.
One link to check:
"BUG: GetIDsOfNames Returns Wrong Function Identifier on Computers Running
Windows 95, Windows 98, or Windows Me"
http://support.microsoft.com/?id=315485
If it won't help, it's possible to see injected code by compiling with /Fx
switch and clarify situation by digging in the merged code.
And related MSDN Magazine article, which would be useful as well:
"C++ Attributes: Make COM Programming a Breeze with New Feature in Visual
Studio .NET"
http://msdn.microsoft.com/msdnmag/issues/01/04/attributes/attributes.asp
..
Regards,
Vadim.
"Vadim Melnik" <vmn...@REMOVETHISdocsultant.com> wrote in message
news:%23S$xSpkSD...@TK2MSFTNGP11.phx.gbl...
This is a complete hack to test things out, but in my class defined copy of
__VariantChangeType I change the lines
} else {
::VariantClear(pvargDest);
*pvargDest = *pvargSrc;
}
return hr;
with this, and it works. This code is completely unsafe, but in this test is
not a problem since the VT is always a simple type.
} else {
static VARIANT v=*pvargSrc;
pvargDest=&v;
}
return hr;
Can anyone shed any light on why this works? Is it a bug?
"David Shepherd" <da...@daveshep.com> wrote in message
news:bev38l$7g5$1...@titan.btinternet.com...
--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnic...@mvps.org
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================
"David Shepherd" <da...@daveshep.com> wrote in message news:bevale$km5$1...@titan.btinternet.com...
After a bit more testing today, I found that the attributed implementation
of Invoke does indeed change the dispatch parameters passed on the stack to
Invoke, while the IDispatchImpl<> implementation does not. With my property
types, I am seeing a conversion from VT_DISPATCH to VT_I4, and this is the
cause of my problem since object reference counts are being decremented as
part of the conversion. I *Think* VBScript is not expecting the reference to
change and so either does not addref() it before the call to Invoke, or does
a release() on it afterwards, but it is so hard to tell without the source
code. There could be a bug here, either in VBScript or in the injected
Invoke, but I do not know enough about COM calling conventions to determine
which one.
I want to do a fresh project which just uses VBScript and a simple
attributed ATL control, if the problem still occurs then Microsoft have a
problem either way. If this is the case, what can I do to get them to fix
it?
"Alexander Nickolov" <agnic...@mvps.org> wrote in message
news:O26u42lS...@tk2msftngp13.phx.gbl...
"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:bf0na8$s1j$1...@sparta.btinternet.com...
Personally to date I have avoided attributed ATL objects, and now, boy am I
glad I did. This is pretty bad.
Brian
"David Shepherd" <da...@daveshep.com> wrote in message
news:bf0na8$s1j$1...@sparta.btinternet.com...
> I think I'm getting somewhere with this now. It is very late here so this
> might not be entirely accurate, but __VariantChangeType is completely
> confusing, the source and destination arguments dont make sense, the source
> is never used except as a temporary variable that should have been declared
> inside the function, and the destination acts as an in/out and so changes
> the dispatch parameter on the stack as part of the conversion process, is
> this good or bad? I dont know, but by preserving the parameter my program
> stops crashing. My conversion is from IDispatch to VT_I4 by the way, which
> will convert the IDispatch default value, to a LONG.
>...
> Can anyone shed any light on why this works? Is it a bug?
The __VariantChangeType's mistake (among other factors) is the
Clearing of pvargDest after following statements:
if (pvargDest->vt == (VT_VARIANT | VT_BYREF)) {
pvargDest = V_VARIANTREF(pvargDest);
}
...
::VariantClear(pvargDest);
It's totally wrong. The VARIANT with VT_BYREF don't have the ownership
and should not free any value of the referenced VARIANT.
PS
I have also met the wrong conversion VT_I4 -> VT_R8 with
__VariantChangeType function. It is made without int-to-double
conversion at all.