ObjRelease needed when using ComObjValue+ObjAddRef?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Coco
Posts: 771
Joined: 29 Sep 2013, 20:37
Contact:

ObjRelease needed when using ComObjValue+ObjAddRef?

09 Oct 2014, 22:24

I was trying to modify jethrow's IsMemberOf function to make it more future-proof. So the question is, do I need to call ObjRelease for pDisp.? Sean (and Lexikos) did mention to release the unwrapped pointer however as per AHK docs:
Docs(ComObjValue) wrote:For instance, if an interface pointer is returned, Release should not be called, but AddRef may be required depending on what the script does with the pointer.
source: ComObjValue
Here is the function:

Code: Select all

IsMemberOf(obj, name)
{
	pDisp := ComObjValue(obj), ObjAddRef(pDisp) ;// ComObjUnwrap()
	GetIDsOfNames := NumGet(NumGet(pDisp + 0), 5*A_PtrSize)
	VarSetCapacity(IID_NULL, 16, 0)
	r := DllCall(GetIDsOfNames, "Ptr", pDisp, "Ptr", &IID_NULL, "Ptr*", &name, "UInt", 1, "UInt", 1024, "Int*", DISPID)
	ObjRelease(pDisp) ;// needed??
	return (r == 0) && (DISPID + 1)
}
lexikos
Posts: 9592
Joined: 30 Sep 2013, 04:07
Contact:

Re: ObjRelease needed when using ComObjValue+ObjAddRef?

10 Oct 2014, 04:11

If you are returning an interface pointer, you don't want to release it, because it will be invalid by the time the caller gets it. You need that copy of the pointer to be counted, otherwise when the caller releases it, the count will be incorrect. So if you're copying the pointer from somewhere else (such as the wrapper object, via ComObjValue) and then returning it, you need to AddRef.

But you aren't returning the interface pointer.

Just think about how the reference count will change.
  • Say obj contains a wrapper object with the only copy of the interface pointer, so refcount = 1.
  • ComObjValue returns the interface pointer, still with refcount = 1.
  • ObjAddRef is called, refcount = 2.
  • You do some stuff which doesn't affect the refcount (as far as you know).
  • ObjRelease is called, refcount = 1.
If the function is called again, the result will be the same. If ObjRelease wasn't called, the reference count would increase by 1 each time you call the function.

In this case, I wouldn't bother with AddRef or Release. You know that from start to finish, obj will contain a reference to the wrapper object. There is no documented way to modify the value (interface pointer) of the wrapper object, so it will remain valid until the wrapper object is freed, which won't happen until after the function returns.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Araphen, Insanibaccha and 219 guests