harrow@bagels.dec.com (Jeff Harrow, NMSG LKG2-2/Y10 DTN=226-5564) (10/05/88)
I've got a programming question (which will show my weakness in Pascal... Oh well) I'm trying to use the HelpCompiler that came over Usenet. It places help text and a CODE resource into a program, which you call with the following "C" code: #include <MacTypes.h> ShowHelp() { Handle rsrcH; ProcPtr pp; if (rsrcH = GetResource('CODE', 2000)) { HLock(rsrcH); pp = (ProcPtr) *rsrcH; (*pp)(); ReleaseResource(rsrcH); } } Now, I tried to convert this to Pascal (Lightspeed, of course) as follows: procedure ShowHelp; var rsrcH : Handle; pp : ProcPtr; begin if rsrcH = GetResource('code', 2000) then begin HLock(rsrcH); pp := @rsrcH; pp; <<<<<THIS, nor @PP, nor (@PP) works<<<<<<<< ReleaseResource(rsrcH); end; end; but I can't figure out how to actually EXECUTE the code, whose entry point address should, I think, be in pp. (Some varients I tried are shown above.) I know that you have to be tricky in Pascal to do this, but what am I missing? Thanks, Jeff Harrow Work address: ARPAnet: HARROW%BAGELS.DEC@decwrl.ARPA Usenet: decwrl!bagels.dec.com!harrow or {allegra,Shasta,decvax}!decwrl!dec-rhea!dec-bagels!harrow Easynet: BAGELS::HARROW Telephone: (508)486-5564 USPS: Digital Equipment Corp. Mail stop: LKG2-2/Y10 550 King St. Littleton, MA 01460
earleh@eleazar.dartmouth.edu (Earle R. Horton) (10/05/88)
In article <8810051239.AA09466@decwrl.dec.com> harrow@bagels.dec.com (Jeff Harrow, NMSG LKG2-2/Y10 DTN=226-5564) writes: >I'm trying to use the HelpCompiler that came over Usenet. It >places help text and a CODE resource into a program, which you >call with the following "C" code: ... >Now, I tried to convert this to Pascal (Lightspeed, of course) as >follows: > >procedure ShowHelp; > var > rsrcH : Handle; > pp : ProcPtr; > > begin > if rsrcH = GetResource('code', 2000) then > begin > HLock(rsrcH); > pp := @rsrcH; > pp; <<<<<THIS, nor @PP, nor (@PP) works<<<<<<<< The data type ProcPtr technically points to an arbitrary type, I think it is SignedByte in Pascal. Therefore there is no way to call the routine directly from Pascal, without using assembly language or InLine assembly. Something like the following should work: PROCEDURE CallCodeResource(theProc: ProcPtr); INLINE $205F,$4E90; {MOVE.L (A7)+,A0 JSR (A0) } This InLine code pops the ProcPtr off the stack, then does a JSR to it, putting the real return address on the stack. You would use it by: CallCodeResource(pp); This, of course, assumes that LightSpeed Pascal allows InLine declarations using the same syntax used by MPW Pascal. Earle R. Horton. 23 Fletcher Circle, Hanover, NH 03755 (603) 643-4109 Sorry, no fancy stuff, since this program limits my .signature to three
oster@dewey.soe.berkeley.edu (David Phillip Oster) (10/06/88)
As others have pointed out: 1.) you can use inline code 2.) you can use an assembly language glue routine linked into your program. Now: 3.) you can use pascal itself. Pascal lets you write routines with procedure valued parameters. Just call it with the argument: procedure callpascal(procedure a(b:integer); b:integer); begin a(b); end; now, suppose foo is a procedure pointer variable. if you say: callpascal( appropriatecasttocircumventpascaltypechecking(foo), 22); it will do the right thing. You can play games by breaking the program up into multiple files and declaring callpascal() differently where it is defined from where it is used. --- David Phillip Oster --When you asked me to live in sin with you Arpa: oster@dewey.soe.berkeley.edu --I didn't know you meant sloth. Uucp: {uwvax,decvax,ihnp4}!ucbvax!oster%dewey.soe.berkeley.edu
iand@munnari.oz (Ian Robert Dobson) (10/06/88)
> > I know that you have to be tricky in Pascal to do this, but what > am I missing? > Apple mentions in Inside Mac 1 that there is no way the Lisa Pascal compiler can call a routine pointed to by a ProcPtr. Probably the same problem exists with LightSpeed Pascal. Does anybody know a way around this with INLINEs? Apart from that, your translation of C to Pascal is incorrect. The C statement "if (rsrcH = GetResource('code',2000)" includes an assignment, NOT a equality comparison. This should be translated as: rsrcH := GetResource('code',2000); if rsrcH <> nil then .... Ian R. Dobson University of Melbourne munnari!iand
singer@endor.harvard.edu (Rich Siegel) (10/06/88)
In article <8810051239.AA09466@decwrl.dec.com> harrow@bagels.dec.com (Jeff Harrow, NMSG LKG2-2/Y10 DTN=226-5564) writes: >I've got a programming question (which will show my weakness in >Pascal... Oh well) > > >Now, I tried to convert this to Pascal (Lightspeed, of course) as >follows: > >procedure ShowHelp; > var > rsrcH : Handle; > pp : ProcPtr; > > begin > if rsrcH = GetResource('code', 2000) then > begin > HLock(rsrcH); > pp := @rsrcH; > pp; <<<<<THIS, nor @PP, nor (@PP) works<<<<<<<< > ReleaseResource(rsrcH); > end; > end; > >but I can't figure out how to actually EXECUTE the code, whose >entry point address should, I think, be in pp. (Some varients I >tried are shown above.) >I know that you have to be tricky in Pascal to do this, but what >am I missing? Two things to do: First, if you're writing your code resource in C, the main routine should be of type "pascal", as in pascal void main() Second, to call a ProcPtr, you need the following inLine: PROCEDURE CallProc(p : ProcPtr); inline $205F, $4E90; which pops the last argument off the stack, and JSRs to it. So... procedure ShowHelp; var H : Handle; hState : SignedByte; begin H := GetResource('Code', 2000); if H <> NIL) then begin hState := HGetState(h); MoveHHi(h); HLock(h); CallProc(h^); HSetState(h, hState); end end; The calls to HGetState and HSetState ensure that the resource is returned to the same state of locked-ness when you're done with it, instead of unconditionally unlocking it every time. --Rich Rich Siegel Staff Software Developer THINK Technologies Division, Symantec Corp. Internet: singer@endor.harvard.edu UUCP: ..harvard!endor!singer Phone: (617) 275-4800 x305 Any opinions stated in this article do not necessarily reflect the views or policies of Symantec Corporation or its employees.