Re: Caching public objects in ActiveX DLLs [reposted from general.discussion]
- From: "Tony Proctor" <tony_proctor@xxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Sat, 9 Jul 2005 10:46:37 +0100
Method (1) would be my choice Nicholas. Method (3) is a road to disaster and
should be avoided at all costs.
I do use weak references (aka "freeze dried" objects), but only to prevent
having to keep back pointers to parent objects, thus preventing circular
dependencies. Although MSFT recommend calls flow "down" the class hierarchy
for a "well behaved" application, I take a slightly more pragmatic approach.
Another good case for weak references if for creating something a general
Timer class from the SetTimer API. Since the API requires the use of Modules
for the call-backs, it's necessary to prevent the Module having direct
references to all the class instances that currently have a ticking timer.
Tony Proctor
"Nicholas D. Krempel" <ndkrempel@xxxxxxxxxxxxxxxx> wrote in message
news:jTDze.109204$Vo6.83611@xxxxxxxxxxxxxxxxxxxxxxxxxxxx
> Hi,
>
> Apologies for posting this again, not sure which is the right group,
>
> As you may know, an ActiveX DLL can only be unloaded when all references
to
> public objects it provides are released (whether these are external
> references, or within the ActiveX DLL itself). (Or forcefully unloaded
when
> the client app exits.)
>
> This leads me to wonder if anyone has a good solution to the problem of
> holding a reference to one of your own public objects inside the ActiveX
> DLL, without preventing it from unloading when all external references are
> gone.
>
> Here are some possible solutions, does anyone have anything better...
>
> 1) Have a private class module implementing the functionality, which is
used
> internally, and a public class module which is just a wrapper.
>
> 2) Hold some kind of 'weak' reference to the public object internally -
for
> example, only store its address, which is dereferenced when required. This
> would also require the class's terminate event to set a flag somewhere so
> you don't try to dereference a deleted object.
>
> 3) Extreme hack: manually decrement the global reference count used by the
> VB implementantion of DllCanUnloadNow (assuming this is what it does,
which
> seems likely). You would also need to make sure VB cleans up public
objects
> which still exist when the DLL unloads, since it wouldn't have to do this
> under normal circumstances? (but must do with private objects anyway).
>
> None of these are particularly convenient, any neat ideas?
>
> Another more general question is about termination order of class modules,
> modules etc on application exit: is there a good way to have some kind of
> control over this other than the general principals like class modules go
> first, then standard modules. For example, you might have a class
hierarchy
> in which 'child' classes expect their parents to still be around when they
> terminate, but I think if both child and parent objects are still around
> when the app terminates (for example, a standard module has a reference to
> the child object and the child object has a reference to the parent
object),
> then VB will detroy the class modules in an arbitrary order. It seems VB's
> destruction order would be better off the other way round in some ways -
> destroy the standard modules first, then usually all class modules will
drop
> off in their correct orders due to references being released, THEN destroy
> any outstanding class modules (due to circular references for example).
> Obviously it's best to try to avoid destruction order dependencies of this
> sort, but sometimes it's quite hard to.
>
> Does anyone else find it annoying that members of global multiuse objects
> arent globally accessible within the ActiveX DLL itself. The convenient
> workaround is to have a global 'as new' object, but this is bad for
reasons
> related to my first question above (its a self-reference to public object,
> so it will hold your DLL active forever). My current workaround is to put
> all the implementations in a BAS module and call that from within the DLL,
> and have the global multiuse class just a wrapper. Sadly it's even
> non-trivial to write a wrapper class! Consider ParamArray arguments - I
need
> to use Matt Curland's (I think?) ParamArray stealing code to get it into a
> usual array to be passed. Wonder if anyone has a better solution to
(either
> of) these problems too?
>
> Thanks in advance,
>
> Nick Krempel
>
>
.
- References:
- Caching public objects in ActiveX DLLs [reposted from general.discussion]
- From: Nicholas D. Krempel
- Caching public objects in ActiveX DLLs [reposted from general.discussion]
- Prev by Date: Caching public objects in ActiveX DLLs [reposted from general.discussion]
- Next by Date: Is there an easy way to expose class variables in COM builds?
- Previous by thread: Caching public objects in ActiveX DLLs [reposted from general.discussion]
- Next by thread: Is there an easy way to expose class variables in COM builds?
- Index(es):
Relevant Pages
|
Loading