Mark G. Meyers
2004-06-29 20:49:43 UTC
I've done alot of back-reading on ms vb groups on this, and I am left
wondering about this - maybe someone can help me to understand?
Now let's say I've got an instance of MyThing. As I understand it, there's
an IUnknown in there at the base of the vtable that I didn't code, but it's
there.
I have found examples of code that would use a weak reference (with
ObjPtr()), and check for a reference count on an object. I was thinking
what a handy little checker I could have, with a Delete() function that
receives an ITerminate reference (interface that implements Term() where the
object clears it's various, <potential> circular refs), and then go and set
the ref passed into Delete() to Nothing, and if all is well, it gets
destroyed... But how to know if it is?
If there are other refs to the object I'm attempting to destroy, then it
doesn't die. I simply want to know if it gets destroyed - a kind of memory
checker. The approaches I've found seem a bit kludgey. Something like
this:
Public Function GetRefCount(ByVal pUnk As IUnknown) _
As Long
GetRefCount = 0
If pUnk Is Nothing Then Exit Function
' try addref and retval from release - VB CAN'T HANDLE THESE
' pUnk.AddRef
' i = pUnk.Release()
' Debug.Print "I got ---" + i
' Get count from "magic" offset in object
CopyMemory GetRefCount, ByVal ObjPtr(pUnk) + 4, 4
' Adjust to account for references to parameter
GetRefCount = GetRefCount - 3
End Function
-------------------------------------------
And another:
Public Function RefCount(ByVal unk As IUnknown) As Long
Dim RefCountAddr As Long
Dim RefCounter As Long
RefCountAddr = ObjPtr(unk) + 4
If RefCountAddr = 4 Then
RefCount = 0
Exit Function
End If
CopyMemory RefCounter, ByVal RefCountAddr, 4
RefCount = RefCounter - 2
End Function
---------------------------------------------
And, wait, but they both work on my class types, but they don't offset the
same way. One subtracts 3, the other subtracts 2. (?)
SO HERE'S THE QUESTION....
Why not, and I would be looking for help figuring out how to do this... Mock
up AddRef and Release declarations that are legal in VB, and caste, starting
with the pointer passed in to GetRefCount() to the values in the 2nd and 3rd
entries of that object's vtable? Then, can I also caste the AddRef/Release
params/return values and "math" them to workable values? Effectively, make
the calls to AddRef() and Release() legal-eze in VB...? Since I haven't
seen this done, there must be some reason why, but I don't know what it is.
Incidentally, if a wee bit of C++ called from VB would do the trick, I'd be
interested. I've watched some of the dissassembly of the VB VM decrementing
references - hardcoded stuff - it's not COM and it's not in my EXE. It's in
MSVBVM60.DLL. Hey, they can do it... (why can't I?)
I would implement Delete() if I knew I could trap a caller deleting when
refs were still outstanding.
Well, very curious as to what the experts have to say.
TIA!
- Mark
ITerminate:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=ulWekD%23TEHA.2944%40tk2msftngp13.phx.gbl&rnum=1&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DUTF-8%26selm%3DulWekD%2523TEHA.2944%2540tk2msftngp13.phx.gbl
wondering about this - maybe someone can help me to understand?
Now let's say I've got an instance of MyThing. As I understand it, there's
an IUnknown in there at the base of the vtable that I didn't code, but it's
there.
I have found examples of code that would use a weak reference (with
ObjPtr()), and check for a reference count on an object. I was thinking
what a handy little checker I could have, with a Delete() function that
receives an ITerminate reference (interface that implements Term() where the
object clears it's various, <potential> circular refs), and then go and set
the ref passed into Delete() to Nothing, and if all is well, it gets
destroyed... But how to know if it is?
If there are other refs to the object I'm attempting to destroy, then it
doesn't die. I simply want to know if it gets destroyed - a kind of memory
checker. The approaches I've found seem a bit kludgey. Something like
this:
Public Function GetRefCount(ByVal pUnk As IUnknown) _
As Long
GetRefCount = 0
If pUnk Is Nothing Then Exit Function
' try addref and retval from release - VB CAN'T HANDLE THESE
' pUnk.AddRef
' i = pUnk.Release()
' Debug.Print "I got ---" + i
' Get count from "magic" offset in object
CopyMemory GetRefCount, ByVal ObjPtr(pUnk) + 4, 4
' Adjust to account for references to parameter
GetRefCount = GetRefCount - 3
End Function
-------------------------------------------
And another:
Public Function RefCount(ByVal unk As IUnknown) As Long
Dim RefCountAddr As Long
Dim RefCounter As Long
RefCountAddr = ObjPtr(unk) + 4
If RefCountAddr = 4 Then
RefCount = 0
Exit Function
End If
CopyMemory RefCounter, ByVal RefCountAddr, 4
RefCount = RefCounter - 2
End Function
---------------------------------------------
And, wait, but they both work on my class types, but they don't offset the
same way. One subtracts 3, the other subtracts 2. (?)
SO HERE'S THE QUESTION....
Why not, and I would be looking for help figuring out how to do this... Mock
up AddRef and Release declarations that are legal in VB, and caste, starting
with the pointer passed in to GetRefCount() to the values in the 2nd and 3rd
entries of that object's vtable? Then, can I also caste the AddRef/Release
params/return values and "math" them to workable values? Effectively, make
the calls to AddRef() and Release() legal-eze in VB...? Since I haven't
seen this done, there must be some reason why, but I don't know what it is.
Incidentally, if a wee bit of C++ called from VB would do the trick, I'd be
interested. I've watched some of the dissassembly of the VB VM decrementing
references - hardcoded stuff - it's not COM and it's not in my EXE. It's in
MSVBVM60.DLL. Hey, they can do it... (why can't I?)
I would implement Delete() if I knew I could trap a caller deleting when
refs were still outstanding.
Well, very curious as to what the experts have to say.
TIA!
- Mark
ITerminate:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=ulWekD%23TEHA.2944%40tk2msftngp13.phx.gbl&rnum=1&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DUTF-8%26selm%3DulWekD%2523TEHA.2944%2540tk2msftngp13.phx.gbl