CompuServe Thread

#swapping handles

6 messages in this thread
#7072From: Jim DillJul 16, 1993 10:20 AM
I would find it handy to be able to take two objects and swap their handles, so that the handle of one pointed to the data of the other and vice versa. Like this: void HSwap(CObject *o1, CObject *o2) { Handle h1 = o1, h2 = o2; Ptr p1 = *h1, p2 = *h2; *h1 = p2; *h2 = p1; } (with appropriate HLocking added). For one thing, this would make for an elegant Do/Undo scheme, in which you could save an object before Doing anything to it, then on Undo or Redo, just swap handles. Is there any danger in this? — Jim
#7108From: Joe SewellJul 17, 1993 9:47 PM
I know that, under Symantec C++ with virtual methods, you're probably begging for trouble doing this. More than likely you'll have trouble under THINK C, also. I'm not certain, but it's quite probable that the handle to an object points to more than just the "data" (instance variables). There's probably also some information to make virtual functions work correctly, and to make the member function do its thing. I would suggest using the standard TCL way of doing Undo, by using a task. Joe
#7123From: jud spencerJul 18, 1993 5:53 PM
Jim, I am not sure if you can dereference an object the way that you are trying to. But if you were instead to something like the following: void HSwap(CObject *o1, CObject *o2) { Handle h1 = (Handle) o1, h2 = (Handle) o2, temp; long objSize; temp = NewHandle(objSize = GetHandleSize(h1)); BlockMove(*h1, *temp, objSize); BlockMove(*h2, *h1, objSize); BlockMove(*temp, *h2, objSize); DisposHandle(temp); } It should work correctly, AS LONG AS THE TWO OBJECTS ARE FROM THE SAME CLASS, and they are both derived from __machdl or __pasObject (?… If they are handle objects). There is vTable Information stored within each class, but it is identical for every object of that class. jud spencer
#7159From: Ken BroomfieldJul 19, 1993 2:29 PM
Jim– I think the other replies to you message may be confused at least in talking about virtual method tables and classes. Jud is probably right that you'll have to copy the object contents. At first glance, what you're proposing ought to work: simply swapping the master pointers which are pointed to by the two handles. Unfortunately, I don't think it can be done quite this simply because the block header (located before the object's data block itself and maintained by the Memory Manager) contains a copy of the handle (actually a "relative handle"). If you just changed the master pointer as you propose, the handle in the block header would be wrong. I'm not sure how this copy of the handle in the block header is used–it is certainly used by the RecoverHandle function, which converts a block pointer back to a handle, but there are probably other reasons that this handle is maintained. Of course, you could update the handle in the block header also, but then you'd be dependent on the structure of the block header (which may have changed with System 7 and 32-bit mode). Look at the Memory Manager chapter in Inside Mac Vol. I for details about the block header. I think Vol. VI has more info about how these data structures were changed for System 7; it probably contains strong words to the effect of, "any programmer trying to manipulate Memory Manager internal structures will be sent straight to MacHell." Hope this helps. –Ken
#7196From: Steve StockmanJul 20, 1993 4:01 AM
Ken: >>> Look at the Memory Manager chapter in Inside Mac Vol. I for details about the block header. I think Vol. VI has more info about how these data structures were changed for System 7 <<< No. Inside Mac completely omits 32-bit Memory Mgr data structures. I'm sure that was done deliberately to prevent programmers from depending on them. They could conceivably change again. Block headers in 32-bit mode have a very similar structure as in 24-bit mode, but they are 12 bytes instead of 8. Steve
#7216From: Jim DillJul 20, 1993 12:34 PM
Ken, Thanks much for that explanation. You're right, I didn't really see the reasons behind the other cautionary messages, other than the general notion that "if it ain't in IM, don't do it." — Jim