Attributed ATL and VBScript

9 views
Skip to first unread message

David Shepherd

unread,
Jul 14, 2003, 4:19:33 PM7/14/03
to
Hi

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

Vadim Melnik

unread,
Jul 14, 2003, 4:57:07 PM7/14/03
to
Hi,

> 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.


David Shepherd

unread,
Jul 14, 2003, 5:17:33 PM7/14/03
to
Thanks Vadim
The Win9x problem is not going to be the cause for me since I am developing
on XP, but is very useful to know about for the future. I just hope to find
something out from the injected code, and __VariantChangeType looks like
a lot of fun to understand :)

"Vadim Melnik" <vmn...@REMOVETHISdocsultant.com> wrote in message
news:%23S$xSpkSD...@TK2MSFTNGP11.phx.gbl...

David Shepherd

unread,
Jul 14, 2003, 6:25:50 PM7/14/03
to
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.

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

unread,
Jul 14, 2003, 7:17:37 PM7/14/03
to
Can you post the whole function? I'm sorry, I don't have VC7.x...

--
=====================================
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...

David Shepherd

unread,
Jul 15, 2003, 7:07:52 AM7/15/03
to
Hi Alexander
I tried to post the source code for __VariantChangeType, but it is quite
hard to read in the Visual Studio editor, and even worse when all the lines
are split in half :)

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...

Igor Tandetnik

unread,
Jul 15, 2003, 11:46:19 AM7/15/03
to
I can confirm. The attributed implementation of IDispatch for dual
interfaces is broken beyond belief. __VariantChangeType modifies the
variant in place (and it does not even do that correctly), and
attribute-generated code passes pointers straight from DISPPARAMS
structure. The whole construct cheerfully trashes [in] parameters.
--
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:bf0na8$s1j$1...@sparta.btinternet.com...

Brian Muth

unread,
Jul 15, 2003, 12:15:51 PM7/15/03
to
Great catch, David. This is an invaluable contribution.

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...

Vi2

unread,
Jul 16, 2003, 12:52:12 AM7/16/03
to
"David Shepherd" <da...@daveshep.com> wrote in message news:<bevale$km5$1...@titan.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.

Reply all
Reply to author
Forward
0 new messages