Re: various objects in my VB6 project - Calling IUnknown

From: Mark G. Meyers (mmeyers[at]hydromilling.com)
Date: 06/30/04


Date: Wed, 30 Jun 2004 13:07:37 -0400


"Peter Young" <youngpa@comcast.no.net.spam.please> wrote in message
news:eS2DabrXEHA.3972@TK2MSFTNGP12.phx.gbl...
> "Mark G. Meyers" <mmeyers[at]hydromilling.com> wrote in message
news:O3FkAyqXEHA.312@TK2MSFTNGP12.phx.gbl...
> > "Peter Young" <youngpa@comcast.no.net.spam.please> wrote in message
> > news:ughtGbiXEHA.3120@TK2MSFTNGP12.phx.gbl...
> > > "Mark G. Meyers" <mmeyers[at]hydromilling.com> wrote in message
> >
> > It encapsulates the act of the object clearing up it's references before
> > setting the ref to nothing.
>
> Let me be sure I understand this - you want to be able to be sure that an
object releases all references it holds to
> *other* objects before terminating it? You'd need some sort of global
object that monitored all AddRef and Release
> calls, so that when an object was to be destroyed, this global manager
could look up which other objects were referenced
> by this one.
>

Peter, it's in the ITerminate example. The object frees up it's references
when it's Term() member is called, as only that object knows how to do.

With static class members, both creation and destruction could be elegantly
contained as in the example, where the in-house rule is, "Every class must
implement ICreateDestroy", for example.

> VB pretty much does this for you.
>
> If an object goes out of scope, VB will clean up that object. If you've
created a circular reference, yes, you're in
> trouble. Don't create circular references. Manually release all references
before terminating an object in your
> Class_Terminate event. It's pretty simple.
>

Right - "don't create circular references". Noone ever told me how or why
such a thing would constitute bad programming practices, but because of this
situation in VB, it is. It's been a bit of a pain to do design work on a VB
project based moreso on general OOD principals, without so much actual VB
experience.

>
> > BEGIN RANT...
> > I think VB doesn't offer garbage collection as much as it does garbage.
>
> Hmmm...
>
> Public Function Whatever( ) As Variant
> Dim o As Object
> Set o = New Collection
> End Sub
>
> That code creates a new COM object *and* releases it automatically, and
creates and returns a Variant, and returns an
> HRESULT to the caller. All that with 2 lines of code and a function
footprint.
>
> Show me the same thing in C++, and then tell me VB doesn't manage
resources well.
>

Variant Foo()
{
    Collection C("and cool constructors, too!");
    Object * pObj = C;
}

Done!

This is the difference between recognizing stack space and heap space.
Frankly, the heap is going to be used quite a bit less in C++ than it will
in VB because of this. Now look at this example of hand-coded object
construction...

----------------------------------
Option Explicit
' class DisplayArmCalcsTask

Private Const mnArmSegments = 3 ' just the arm segments
Private Const mnTotalSegments = 5 ' number of segments - arm and
calibration
Private Const mnStateVars = 12 ' total number of (local) statevars
Private Const mnArmEncoders = 3 ' number of arm encoders

Private mcSegLens(1 To mnTotalSegments) As TextBox
Private mcArmCoords(mnTotalSegments + 1 To mnStateVars) As TextBox
Private mrStateVars(1 To mnStateVars) As StateDouble
Private mrEncoders(1 To mnArmEncoders) As Encoder

Private Sub Class_Initialize()
    ' Get local refs for the arm calc objects
    Set mrStateVars(StateVarIndexes.ArmSegA_) = _
        grControllerCard.GetNamedObject(g.StateDoubles.ArmSegLenA.Name)
    Set mrStateVars(StateVarIndexes.ArmSegB_) = _
        grControllerCard.GetNamedObject(g.StateDoubles.ArmSegLenB.Name)
    Set mrStateVars(StateVarIndexes.ArmSegC_) = _
        grControllerCard.GetNamedObject(g.StateDoubles.ArmSegLenC.Name)
    Set mrStateVars(StateVarIndexes.ArmSegCalOne_) = _
        grControllerCard.GetNamedObject(g.StateDoubles.ArmCalSegLenOne.Name)
    Set mrStateVars(StateVarIndexes.ArmSegCalTwo_) = _
        grControllerCard.GetNamedObject(g.StateDoubles.ArmCalSegLenTwo.Name)

    Set mrStateVars(StateVarIndexes.ShoulderX_) = _

grControllerCard.GetNamedObject(g.StateDoubles.ArmShoulderAxisX.Name)
    Set mrStateVars(StateVarIndexes.ShoulderY_) = _

grControllerCard.GetNamedObject(g.StateDoubles.ArmShoulderAxisY.Name)

    <SNIP - there is much more of this!!!>
     yes I know it looks like it should be in a loop, whatever, there's at
least 4 loops of this stuff here anyhow
End Sub

Actually, I para-coded it, I have a variety of Initxxx() methods for
bringing all this crap up initially. Every object-member of an object has
to have it's own New operation performed on it, and that can generate quite
a bit of code.

--------
Consider the following distinction, and I think this will help sort out what
we're talking about. Of course that which "by all rights" appears on the
stack goes as quickly as it comes. I think where VB offers the advantage is
in coding for polymorphism. I exercise it's polymorhic abilities
extensively, with a variety of small interfaces, and pass-through functions
to the default interface on all of them. Also a bit of extra code piling up
to do the pass-throughs, but nice when implemented.

Conversely to stack allocation, the things I tend to put to the heap don't
come and go within the scope of a single function. They tend to be a bit
more persistent, as objects, referenced by module-scope or global-scope
variables.

>
> > And
> > what is the difference between 'friend' and 'public' exactly?
>
> Friend is visible within the project. Public is visible outside the
project.
>

Right. Reeeeeeeeaaaaallly friendly. When I split things into a
multi-programmer situation, I was faced with the idea of protecting access
to some things and not others. Then the extensive polymorphism came into
play, but, frankly, for just being protective, it doesn't seem worth it
(in-house, we're all friendly here). On a few classes, I made "client-side"
interfaces that included, for example, all the read properties but not the
writes. A ref to the default interface would be "server-side". There is a
small example of this style in the ITerminate sample. I call it
"inheritence through encapsulation".

I haven't gotten into multi-project development yet. Am I missing something
good? It's just an EXE - no real COM objects or multiple threads or
processes needed.

> > In this
> > case, we got New, and we got no Delete.
>
> You are aware of Nothing, right? Or are you drawing a distinction because
Nothing is really just saying "remove my
> reference"?
>

Yes, and yes, there is no delete. I think architecturally what we're
playing with here is that the creators of objects cannot (or may not be able
to) destroy the objects that they create. Cool, the creator can die and the
created remains, and yet, some people might not like that.

>
> > Ever see your COM subsystem just
> > lock up on you, and applications become unstable?
>
> Nope.

Happened to me working with the clipboard. Maybe rightfully so, then.
Everybody uses it.

>
> > Lest we avoid ActiveX or
> > DCOM for security purposes. Oh, and I benchmarked pipes vs COM for
> > inter-proces communications a few years ago on a Win2K box. The pipes
were
> > only 70,000 times faster...
>
> Since when is COM used for IPC?
>

I created Browser Helper Objects that launched in processes (every explorer
instance) to communicate with other processes on the machine. At this
point, I don't even recall exactly how I tried the COM IPC, something to do
with sync'ing. It was no doubt floundering amidst O/S time-slicing, perhaps
amongst other things. Btw: this was happening prior to IE windows all
running in the same process (which kind of bugs me as a user, as now one
mis-behaving IE window easily kills them all).

-----------------

Frankly, I haven't taken the opportunity to blow off steam since starting
this VB adventure. Hope y'all don't mind - felt like a bit of a rant!
There's dozens of gripes against the C++ lexicon responding to the political
powers of when it came into being (there's a book on it). Maybe it happens
everywhere, but, MS has a unique way it seems to me to create an ambiguous
instruction set that just wouldn't survive a yacc. I saw it happen with an
OLAP tool (prior to development), and I still get wiered out by legally
coding sub calls vs function calls - with or without parenthesis, or with or
without the word 'Call'. It's all that Office VBA stuff, and that gets
quite fluffy nutterbox, too, like the ! symbol in Access, or maybe a dot, or
whatever. Syntactically ambiguous or vague, inter-related, dependent,
separate, and yet, integrated - funboxes!

Have a happy, and I'll try to do the same -
Mark



Relevant Pages

  • Re: Sangband is back.
    ... I'm not sure if this should go privately (since technically it's a bug ... sent a private bug report to a maintainer of a variant I got no response ... than modifying the references in the Makefile appropriately). ...
    (rec.games.roguelike.angband)
  • Re: Late Binding of COM components
    ... A workaround for this is to collect up the Office 11 PIA's and place them on your development machine and add references to these PIA's rather than the Office 12 PIA's. ... Private Const ProgID As String = "Excel.Application" ... Private m_type As Type ... Private Sub Button1_ClickHandles Button1.Click ...
    (microsoft.public.dotnet.languages.vb)
  • disappearing controls
    ... I have a few custom controls that I set up on a form and tested setting ... After adding those references, and no other changes to my form.... ... private Bloodhound.BHTabControl bhTabControl1; ... did a definition that needed the references and it didn't compile... ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: disappearing controls
    ... I have seen this happen with Visual Inheritance when attempting to change ... > After adding those references, and no other changes to my form.... ... > private Bloodhound.BHTabControl bhTabControl1; ... > I have had designer-set properties ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Setting a reference to a libray in code
    ... References.Remove Ref it shows an error. ... As soon as the reference is missing though it fails you cant remove it ... to replace broken references with downlevel references. ... Select Case strGUID ...
    (microsoft.public.access.formscoding)