Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using the "same dll" to create Globals across apps

0 views
Skip to first unread message

Ruffin Bailey

unread,
Dec 5, 2003, 3:37:56 PM12/5/03
to
I'd like to create a dll with the following code in a single Class
file:

'====================================================
Option Explicit

Public strDate As String

Private Sub Class_Initialize()
Me.strDate = Now
End Sub
'====================================================


... and create it in such a way that no matter how many apps create an
instance of the Class, strDate is always the same. That is, if I
created an .exe that displays a Form with a Textbox on it with this
code:


'====================================================
Private Sub Form_Load()
Dim clsTest as Class1
Set clsTest = new Class1

Me.Text1.Text = Class1.strDate
End Sub
'====================================================

... *every instance* of the .exe would have *the same* text --
specifically text with the time that the first Class was initialized.
When all references to the Class dropped, the Now value in strDate
should drop as well.

To recap, then, I want to create a dll with a single Class that
initializes some values (seems the Class_Initialize method is the
place to do this) and every anonymous exe that references that dll and
creates an instance of the Class will see the same variable value --
like a Global var across exe's using a dll as an initialization point
and a bridge to other objects. When all instances of the Class drop
from memory, so should the persisted value(s).

I would prefer not to refactor the dll's instantiation to some central
location and store values in the registry, as the objects that
instance the Class should be self-contained and shouldn't need to know
about other objects. I've been messing with the Instancing property
(GlobalMultiUse initially seemed promising) of classes and a little
with the Persistable property, but don't think that's the ticket.

Thanks,

Ruffin Bailey

Andrew Faust

unread,
Dec 5, 2003, 4:16:58 PM12/5/03
to
On 5 Dec 2003 12:37:56 -0800 kab...@atari.net (Ruffin Bailey) blurted out:

>I'd like to create a dll with the following code in a single Class
>file:
>
>'====================================================
>Option Explicit
>
>Public strDate As String
>
>Private Sub Class_Initialize()
> Me.strDate = Now
>End Sub
>'====================================================
>
>
>... and create it in such a way that no matter how many apps create an
>instance of the Class, strDate is always the same. That is, if I
>created an .exe that displays a Form with a Textbox on it with this
>code:
>
>
>'====================================================
>Private Sub Form_Load()
> Dim clsTest as Class1
> Set clsTest = new Class1
>
> Me.Text1.Text = Class1.strDate
>End Sub
>'====================================================
>
>... *every instance* of the .exe would have *the same* text --
>specifically text with the time that the first Class was initialized.

You can't do this like that. The problem each process that loads the
DLL or even ActiveX for that matter load it's OWN COPY of the code
in to memory. Basically windows runs each process in it's own memory
space so that even if one process goes down it doesn't take the
whole system down. (Like Windows used to.)

Go to Google and searched for Memory Mapped files. They can help
you to share memory across multiple processes.


Andrew Faust

Where are we going and why am I in this handbasket?

Peter Young

unread,
Dec 5, 2003, 5:37:19 PM12/5/03
to
You can use an ActiveX EXE to do this. Unfortunately I don't remember the details. You want to set it up so that there
is only one running instance of the EXE. IIRC, you use a variable in a BAS module which is visible to all objects in the
EXE.

You can also use the Running Object Table. Matt Curland provides a sample with his book that does almost exactly what
you're wanting to do:
www.powervb.com

-Pete

"Ruffin Bailey" <kab...@atari.net> wrote in message news:172e9d35.03120...@posting.google.com...

Ben Taylor

unread,
Dec 6, 2003, 7:24:54 PM12/6/03
to
Use the registry.


"Ruffin Bailey" <kab...@atari.net> wrote in message
news:172e9d35.03120...@posting.google.com...

NickD

unread,
Dec 7, 2003, 8:28:23 AM12/7/03
to

I think an out-of-process activex exe with the class as publicnotcreatable
would do the trick.

With that setting you would use another class (in that exe) whose job it is
to get a reference of this class and pass it back to the caller if it
already exists (and thus, preserving the date/time stamp of the first
instance) or to create it and pass it back (which it can do from within the
.exe) which would set the value for the first instance.

Once all the objects had done their thing and closed, the activex exe can
then also shutdown and release its hold on the value it created for the
first instance. Then the whole thing starts again on the next launch of the
"client" app without any need for you to manage sessions / timeouts /
reference counting of your own in other storage areas (such as the
registry).

There are sample MSDN projects using this approach to share an object and
its values.

Regards,
Nick


Ben Taylor

unread,
Dec 7, 2003, 1:50:13 PM12/7/03
to

> I think an out-of-process activex exe with the class as publicnotcreatable
> would do the trick.

I *know* the registry would do the trick.

>
> With that setting you would use another class (in that exe) whose job it
is
> to get a reference of this class and pass it back to the caller if it
> already exists (and thus, preserving the date/time stamp of the first
> instance) or to create it and pass it back (which it can do from within
the
> .exe) which would set the value for the first instance.

yes, granted. This is the elegant solution. But a lot of people just don't
trust ActiveX. If you *can* get it to work in the required way for the
application you're building, on all the machines it needs to work on, then
use it, it is theoretically the best solution. I suggested the registry as
it provides that little added layer of 'knowing what's going on' for some
users.

NickD

unread,
Dec 7, 2003, 9:49:52 PM12/7/03
to
"Ben Taylor" <nosp@mpleasewerebritish> wrote in message
news:OnTOzLPv...@tk2msftngp13.phx.gbl...
[...]

> I *know* the registry would do the trick.

Well, yes. I don't disagree it could work given the right criteria, but it
would likely require a lot of hand-holding to meet them all. What if your
machine crashes or power goes whilst you have apps loaded in memory that are
relying on a clean exit for dereferencing your home-grown registry data
sharing solution? Will it ever clean up again? Will it only be able to
clean up when some programmed timeout has been reached? Is this an issue?
It might be, they're just part of the pros and cons you have to weigh up for
every solution.

[...]


> yes, granted. This is the elegant solution. But a lot of people just don't
> trust ActiveX. If you *can* get it to work in the required way for the
> application you're building, on all the machines it needs to work on, then
> use it, it is theoretically the best solution. I suggested the registry as
> it provides that little added layer of 'knowing what's going on' for some
> users.

A little practice with ActiveX and it's not so hard to get on with IMO. I
don't recall having any real problems either with deployment and such for
different machines, the only time I did get bitten (but then, I am/was still
learning it) was when I was trying to get services to talk to an out of
process object that had been launched by another (logged in) user and they
weren't seeing each other because of the different user contexts.

So it's just another idea, and I only replied to your post because I had
already lost the original, it wasn't to specifically counter your advice or
anything. I personally wouldn't be happy with having to manage a static
store (like the registry) to mimic dynamic/instance data (unless it was
actually possible to make use of things like HKEY_DYN_DATA at all? I don't
know.. the only tinkering I did with that key I only managed to get
read-only access to), but if you want to and advocate it that's fine.

Regards,
Nick


steve

unread,
Dec 8, 2003, 3:01:15 PM12/8/03
to
you're a freaking idot!

"Ben Taylor" <nosp@mpleasewerebritish> wrote in message
news:OnTOzLPv...@tk2msftngp13.phx.gbl...
|

Ruffin Bailey

unread,
Dec 8, 2003, 3:44:42 PM12/8/03
to
"NickD" <no_emails...@nickd.demon.co.uk> wrote in message news:<OPPa6XMv...@TK2MSFTNGP09.phx.gbl>...

> I think an out-of-process activex exe with the class as publicnotcreatable
> would do the trick.
>
> With that setting you would use another class (in that exe) whose job it is
> to get a reference of this class and pass it back to the caller if it
> already exists (and thus, preserving the date/time stamp of the first
> instance) or to create it and pass it back (which it can do from within the
> .exe) which would set the value for the first instance.
>
...

>
> There are sample MSDN projects using this approach to share an object and
> its values.

Thanks Nick. Looks like we have a winner. As I'd stated in the OP, I
didn't want to use registry entries exactly for the resasons Nick
states later in the thread. Believing Java & C# are doing things The
Right Way with tasks like this one (at least when it comes to
factoring logic correctly), Nick's answer seems to make the most
sense. MSDN warned me off of Steve's similar answer with the phrase,
"You'll be much less likely to encounter object creation time-out
problems and deadlocks that may occur if Sub Main is used to
initialize the component."

In MSDN, the example can be found under the name, "Sharing the
CoffeeMonitor". Here are a few choice snippets:

To create the Connector object

On the Project menu, select Add Module to add a standard module to the
Coffee project. (If you have the Add Module dialog box enabled,
double-click the Module icon when the dialog box appears.) Add the
following variable declarations to the Declarations section:

Option Explicit
Public gCoffeeMonitor As CoffeeMonitor
Public glngUseCount As Long

The variable gCoffeeMonitor is used to keep a reference to the single
shared CoffeeMonitor. The glngUseCount variable keeps track of the
number of Connector objects using the CoffeeMonitor.

On the Project menu, select Add Class Module to add a class module to
the Coffee project. (If you have the Add Class Module dialog box
enabled, double-click the Class Module icon when the dialog box
appears.) In the Properties window, set (Name) to Connector.

Add the following code to the Connector class's code window:
Public Property Get CoffeeMonitor() As CoffeeMonitor
Set CoffeeMonitor = gCoffeeMonitor
End Property

The Connector's read-only CoffeeMonitor property returns a reference
to the single global instance of CoffeeMonitor.

In the Object drop down, select Class to open the template for the
default event (Initialize). Add the following code to create the
global instance of CoffeeMonitor:
Private Sub Class_Initialize()
If gCoffeeMonitor Is Nothing Then
Set gCoffeeMonitor = New CoffeeMonitor
End If
glngUseCount = glngUseCount + 1
End Sub

The first time a client requests a Connector object, it will create
the global CoffeeMonitor. Each Connector object increases the use
count of the CoffeeMonitor.

...

In the Procedure drop down, select the Terminate event for the class.
Add the following code to the event procedure template:
Private Sub Class_Terminate()
glngUseCount = glngUseCount - 1
If glngUseCount = 0 Then
Set gCoffeeMonitor = Nothing
End If
End Sub

...

In the Project Explorer window, double-click CoffeeMonitor to activate
it. In the Properties window, set the Instancing property of the class
to PublicNotCreatable.

...

=================

Thanks again for the help. Haven't refactored my code over just yet,
but that seems bang on the money. (Of course having started this
project in .NET probably would have been the absolute best answer, but
I'll beg out by saying I wasn't around when it was initially spec'd.
Kinda feel like I'm going around my elbow to get to my
nose/well-factored code here.)

Ruffin Bailey

Ben Taylor

unread,
Dec 8, 2003, 7:56:08 PM12/8/03
to
> Well, yes. I don't disagree it could work given the right criteria, but
it
> would likely require a lot of hand-holding to meet them all. What if your
> machine crashes or power goes whilst you have apps loaded in memory that
are
> relying on a clean exit for dereferencing your home-grown registry data
> sharing solution? Will it ever clean up again?

It'd clean up everything on a successful unload, and it wouldn't assume any
valid values on startup. So if it crashed, it wouldn't particularly matter.


Ben Taylor

unread,
Dec 8, 2003, 7:56:23 PM12/8/03
to
yeah, fuck off you twat.


"steve" <a...@abc.com> wrote in message
news:vt9m82h...@corp.supernews.com...

Steve Gerrard

unread,
Dec 8, 2003, 9:47:36 PM12/8/03
to

"Ruffin Bailey" <kab...@atari.net> wrote in message
news:172e9d35.0312...@posting.google.com...

> "NickD" <no_emails...@nickd.demon.co.uk> wrote in message
news:<OPPa6XMv...@TK2MSFTNGP09.phx.gbl>...
> Thanks Nick. Looks like we have a winner. As I'd stated in the OP, I
> didn't want to use registry entries exactly for the resasons Nick
> states later in the thread. Believing Java & C# are doing things The
> Right Way with tasks like this one (at least when it comes to
> factoring logic correctly), Nick's answer seems to make the most
> sense. MSDN warned me off of Steve's similar answer with the phrase,
> "You'll be much less likely to encounter object creation time-out
> problems and deadlocks that may occur if Sub Main is used to
> initialize the component."
>
> In MSDN, the example can be found under the name, "Sharing the
> CoffeeMonitor". Here are a few choice snippets:
>

Certainly a global "CoffeeMonitor" style object can be used, if you need
the full capabilities of a global object. My example was in response to
your specific request for a way to retrieve a global StartTime for the
module. If that is all you need, then a simple global variable would
suffice. I would never use Sub Main to initialize an object, but it is
fine for initializing a global date variable.

Hope it goes well.

Steve


Ruffin Bailey

unread,
Dec 9, 2003, 10:21:20 AM12/9/03
to
> Certainly a global "CoffeeMonitor" style object can be used, if you need
> the full capabilities of a global object. My example was in response to
> your specific request for a way to retrieve a global StartTime for the
> module. If that is all you need, then a simple global variable would
> suffice. I would never use Sub Main to initialize an object, but it is
> fine for initializing a global date variable.

Good point. Yep, I'm actually throwing objects around, but wanted to
keep things simplest case. If I was actually trying to do what I'd
_said_ I was trying to do (wouldn't it be nice if more people did
that?), your answer was right on the money. Sorry about that, and
thanks for the help.

> Hope it goes well.

We'll see. Installing this week.

Thanks again,

Ruffin Bailey

0 new messages