Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ MUSHclient
➜ VBscript
➜ Saving object references in a dictionary
Saving object references in a dictionary
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| Ked
Russia (524 posts) Bio
|
Date
| Tue 18 May 2004 10:16 AM (UTC) |
Message
| In hopes that someone has a quick answer... I need a way of allowing the user to open several instances of the same COM object, and I'd prefer to implement it in Vbscript. My idea was to have a dictionary, where object references could be stored and accessed by key name through aliases. Would that work? Could I for example retrieve an object from a dictionary by key and set it to Nothing to clean up the reference? How would this look in code? I'd experiment myself, but that would require messing with an existing plugin and I'd rather not do that unless necessary, since my changes tend to be sloppy. So if anyone knows whether this would work or I should give up all hope of using Vbscript for this, I'd appreciate the guidance. | Top |
|
Posted by
| Shadowfyr
USA (1,790 posts) Bio
|
Date
| Reply #1 on Tue 18 May 2004 07:10 PM (UTC) |
Message
| Hmm. I doubt it would work in anything except python, but I am not 100% sure. Usually objects can only be placed into a special structure called a 'collection'. This differs from arrays in some important way, but I am not 100% sure what. I have no idea what would happen if you tried to use an array to hold them. Also, I doubt a sort of dictionary system would necessarilly work either, the syntax is generally "mycollection(index).object_function..." As far as I know there is no such thing as an object dictionary and any thing like that would have to be built from scratch in any language that supported it. | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #2 on Tue 18 May 2004 10:04 PM (UTC) Amended on Tue 18 May 2004 10:05 PM (UTC) by Nick Gammon
|
Message
| My understanding of COM (which is not fabulously great) is that it is effectively an "include" process for object (executable) data rather than source data.
An object reference is simply a pointer to a piece of memory that - for you particular PC - is where that code (or the table of pointers to your code) resides after being loaded into memory.
Taking MUSHclient as an example, it might look like this:
MUSHclient object reference --> (eg. 0x01abc4322)
|
|-- +0 -> QueryInterface
|-- +1 -> AddRef
|-- +2 -> Release
|-- +3 -> Note
|-- +4 -> Send
|-- +5 -> AddTrigger
|-- +6 -> DeleteTrigger
|-- ...
|-- ...
These numbers are not accurate for MUSHclient, they just illustrate the idea.
Thus, given the object reference, you add 3 (times the length of a pointer) to it to get the address of the world.Note routine, which can then be called as a direct function call.
The first one (QueryInterface) is always present for a COM object. It is used to find out about the object.
For instance, you might say (in pseudocode):
Q. What is the ID for AddTrigger?
A. QueryInterface replies: 5
or
Q. What is routine at offset 5?
A. QueryInterface replies: AddTrigger
Actually, reading the help files for COM, the above is not strictly correct, however it is the general idea.
Anyway, AddRef is used to tell COM that there is another "user" of that object (eg. an Excel spreadsheet) and it is to stay in memory until there are no more users.
Lastly, Release is used to tell COM that there is one less "user" of that object, and that if the user count goes to zero the object can be released.
So, to answer your question, I see no problem with copying COM references, provided you are careful. I can't say whether VB "under the bonnet" adds to the reference count when you make copies, and subtracts from the reference count when you say:
set x = nothing
I think I would experiment with a simple example (eg. using GetWorld) and seeing if you can make copies and the copies keep working, especially after you have set the original to "nothing".
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Shadowfyr
USA (1,790 posts) Bio
|
Date
| Reply #3 on Tue 18 May 2004 11:10 PM (UTC) |
Message
| Copies are not a problem. What he wants to do is a bit different. Yes, you could 'in theory' place the object references into a VB Array and have them work. You can't however, split/join, etc. without losing the essential property of it being recognized as an 'object', so it won't even let you do this. It may thus not let you put them in an array in the first place. As for his idea of referencing the object through a dictionary, you simply can't. You could use one array of names to retrieve a temporary copy of the object itself, then call that ones functions, but not use the name to directly talk to it.
Also, when you make a copy of an object in VBScript, you are only copying the reference, not the object. As far as the object is concerned you still only have one 'user' assigned to the COM object, but VB doesn't release that single connection, until you clear all copies of it. Otherwise, you would never be able to make copies of such a reference to move it into or out of a collection or between subs, etc. in VB, if the object was one of those 'one running copy only + one user at a time" kind. | Top |
|
Posted by
| Ked
Russia (524 posts) Bio
|
Date
| Reply #4 on Wed 19 May 2004 10:39 AM (UTC) |
Message
| Doing this sort of thing in Python isn't a problem, at least I don't see why it would be, as everything's essentially an object there, so a reference to a COM object could be placed in a dict without trouble. I am willing to bet that I could do something like: dict['objkey'].UseMethod(arg)
I suspected that using objects from dictionaries in vbscript is next to impossible, although I guess I'll have to try afterall - I managed to get vbscript to do some rather perverted Python-like stuff with arrays before, so maybe that'll work. Maybe temporarily placing the dict item in a local variable and using that variable as if it was an object instance will work. Obviously I could do that in Python, but since the COM object is already written in it and puts some import load on the object's startup, I was hoping to avoid an extra import in the plugin through using vbscript. | Top |
|
Posted by
| Ked
Russia (524 posts) Bio
|
Date
| Reply #5 on Wed 19 May 2004 05:01 PM (UTC) |
Message
| Heh, vbscript never seizes to amaze me, I guess it's not entirely as numb as I might believe it to be. It actually works. Here's a script I used to test it (thanks to Nick for suggesting a Mushclient callback for a guinneapig, that possibility actually never even occured to me):
dim dict
set dict = CreateObject("Scripting.Dictionary")
dict.Add "a", world
dict.Item("a").Note "test"
And while I am at it, this works also:
dim arr1(2), arr2(2)
arr2(0) = "test2"
arr1(0) = arr2
world.Note arr1(0)(0)
Somehow that way of using multi-dimensional arrays had always appealed to me much more than what Microsoft offers for a standard way of doing it. | Top |
|
Posted by
| Shadowfyr
USA (1,790 posts) Bio
|
Date
| Reply #6 on Wed 19 May 2004 08:05 PM (UTC) |
Message
| Hmm.. Interesting. Of course 'technically' what the script is doing is passing an object reference to an external application (the scripting.dictionary), then that is handling the subsequent calls. Actually, a more interesting question is if you could pass such an object (like a button) from one program to another, so that you can assign its 'parent' to a completely different window, then pass along the object reference itself to that windows application to deal with. Bit trickier of a game, but this seems to imply it may be possible to do some spooky stuff with object references. ;) lol | Top |
|
Posted by
| Ked
Russia (524 posts) Bio
|
Date
| Reply #7 on Thu 20 May 2004 12:55 AM (UTC) |
Message
| Passing a button should be possible - it's no different from any other object. But if you wanted to place a button in one app and have it do something in a different one, then how would you bind the button's events? And how would it work if I was to pass an MFC button to a Qt app? Would it recognize it as a button? That's too much dzen for me to handle :) | Top |
|
Posted by
| Shadowfyr
USA (1,790 posts) Bio
|
Date
| Reply #8 on Thu 20 May 2004 11:43 PM (UTC) |
Message
| Actually.. In theory in VB you could create a new control extender, pass the button to the VB application and have it assign the 'object' to the extender object and gain access to its events that way. In theory. I am sure there is a way in C++ too. The biggest issue is that the application you 'attach' it to needs to do the attaching, since even if you tied the object to a window, the programs code would have no idea what to do with it. However, this does bring up the interesting concept that you could say, attach an icon or image, updated by the original application, to another window. Even toolbars possibly, though that is trickier. Your original application would control it and handle most events, but its would appear/disappear along with the program you attached it to as a parent.
Now.. The thing I am not too certain of is what happens if the 'parent' gets closed? It could a) crash your program, b) hang the 'parent', since it can't be released by that windows program, c) crash both, d) crash everything. Until you actually try it, it would be rather hard to say. However, since it is now the 'child' of the program you attached it to, the program may send it a 'terminate' or 'close' event anyway, so you could maybe catch that event and kill the object, thus avoiding the possible problems (assuming the object doesn't recieve the event and terminate itself anyway, or recieves it at all). It would be a rather interesting and bizarre experiment. | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
21,169 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top