Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!mailrus!bbn!husc6!endor!siegel From: siegel@endor.harvard.edu (Rich Siegel) Newsgroups: comp.sys.mac.programmer Subject: Re: Standard File and Desk Accessories Message-ID: <2015@husc6.harvard.edu> Date: 7 Jun 89 15:30:48 GMT References: <50967@tut.cis.ohio-state.edu> <7547@hoptoad.uucp> <4972@umd5.umd.edu> <51276@tut.cis.ohio-state.edu> Sender: news@husc6.harvard.edu Reply-To: siegel@endor.UUCP (Rich Siegel) Organization: Symantec/THINK Technologies, Bedford, MA Lines: 94 In article <51276@tut.cis.ohio-state.edu> Todd A Hitt writes: [adding a resource (!!) to a resource file to hold storage] Yeeeech. I would throw away any program that added resources to a running application without my explicit command. The idea of adding a resource in this manner has some big holes in it: 1. The file is modified. 1a. Doing so changes the mod date, which means that the next time I do an incremental backup, the file has to get backed up for no particularly good reason. 1b. Doing so will set of virus detectors left and right. 2. What if the AddResource fails, perhaps because the disk is write-protected or full? If that happens, you're hosed. 3. As I said, modifying applications without explicit command is repugnant to me. An alternate solution involves some assembly language, and works something like this: Define a 4-byte spot in your code where you can store a handle. Then, allocate the handle with NewHandle, and put it there. Whenever you need your global storage, retrieve the handle from this location and use the handle. The code looks something like this (I'm writing off the top of my head, so forgive me if this doesn't assemble). ;this is where the handle goes HStorage: dc.l 0 ; this routine saves away the handle for you. ; ; procedure SaveAway(h : Handle); ; SaveAway: movea.l (a7)+, a0 ; pop the return address movea.l (a7)+, a1 ; pop the argument move.l a0, -(a7) ; push the return address back. ; a1 now contains the handle we want to store lea @HStorage, a0 ; get the address of our storage move.l a1, (a0) ; put the handle there ; we're done, so return. A more efficient routine might have ;left the return address in a register and done an indirect JMP, ;but this is quickie code. rts ; this routine returns the handle that was saved away. ; procedure GetBack(var h : Handle); ; movea.l (a7)+, a0 ; pop the return address movea.l (a7)+, a1 ; pop the argument move.l a0, -(a7) ; push the return address back. ; a1 now contains the address of the variable to hold our ; handle lea @HStorage, a0 ; get the address of our store handle move.l a0, (a1) ; store it in our variable ; we're done, so return. rts You can assemble this into a .O file, and it should work substantially as written. This scheme is similar to the way that THINK C and THINK Pascal save away A4, but to do globals from A4 requires a little assistance from the compiler and linker. TLSC and TLSP also have jump-table support which allows you to write multi-segment DA's and drivers, and (in TLSP) to write DA's or drivers in Object Pascal. (A rather unique capability, if I may say so myself. :-) --Rich ~~~~~~~~~~~~~~~ Rich Siegel Staff Software Developer Symantec Corporation, Language Products Group Internet: siegel@endor.harvard.edu UUCP: ..harvard!endor!siegel "She told me to make myself comfortable, so I pulled down my pants and sat in the pudding." -Emo Phillips ~~~~~~~~~~~~~~~