newman@ut-emx.UUCP (Dave Newman) (04/07/89)
Here is another question for the net-gods: how do you call a
code resource (like an XCMD or whatever) from another piece of
code? Can it be done from a high-level language? How might it
be done in Pascal?
Thanks,
>>Dave
austing@Apple.COM (Glenn L. Austin) (04/08/89)
In article <11817@ut-emx.UUCP> newman@ut-emx.UUCP (David Newman) writes: >Here is another question for the net-gods: how do you call a >code resource (like an XCMD or whatever) from another piece of >code? Can it be done from a high-level language? How might it >be done in Pascal? In C, it is really *relatively* simple -- all you need to do is create a function pointer. In Pascal, however, you need to have an assembly-language routine to do the actual call. Basically, in order to call a code resource, you need to do the following steps: 1) Load the resource into the heap (with your favorite GetResource call) 2) Move the resource high into the heap (with MoveHHi) 3) Lock the resource (with HLock) 4) Dereference the Handle (C: *handle, Pascal: handle^) 5) Assign the dereferenced handle to your function pointer in C. In Pascal, it depends upon the implementation of your assembly language routine. 6) Call the function! Remember that in C, your function assignment is: functionname = (type (*)()) pointer or easier yet: functionname = (void *) pointer but your function call is (*functionname)() ----------------------------------------------------------------------------- | Glenn L. Austin | The nice thing about standards is that | | Apple Computer, Inc. | there are so many of them to choose from. | | Internet: austing@apple.com | -Andrew S. Tanenbaum | ----------------------------------------------------------------------------- | All opinions stated above are mine -- who else would want them? | -----------------------------------------------------------------------------
han@Apple.COM (Byron Han, wyl E. coyote ) (04/08/89)
In article <28576@apple.Apple.COM> austing@Apple.COM (Glenn L. Austin) writes: >In article <11817@ut-emx.UUCP> newman@ut-emx.UUCP (David Newman) writes: >>Here is another question for the net-gods: how do you call a >>code resource (like an XCMD or whatever) from another piece of >>code? Can it be done from a high-level language? How might it >>be done in Pascal? > >In C, it is really *relatively* simple -- all you need to do is create a >function pointer. In Pascal, however, you need to have an assembly-language >routine to do the actual call. Basically, in order to call a code resource, >you need to do the following steps: > >1) Load the resource into the heap (with your favorite GetResource call) >2) Move the resource high into the heap (with MoveHHi) >3) Lock the resource (with HLock) >4) Dereference the Handle (C: *handle, Pascal: handle^) >5) Assign the dereferenced handle to your function pointer in C. In Pascal, > it depends upon the implementation of your assembly language routine. >6) Call the function! > To wit, if you have a code resource with entry point FUNCTION foom(a, b, c, d, e, f):g you create a pascal function of the following FUNCTION callfoom(a, b, c, d, e, f, x:LONGINT):g; INLINE $205F,$4E90 To call the code resource, use callfoom instead and pass the dereferenced handle as the final argument. Doing it from assembler makes more sense to me since you have better control over register saving and assembler is more efficient. By the way if you are doing this from assembler, it is a REALLY GOOD IDEA to save registers... 2. Memory management. If the code resource has the locked bit set, the code resource will be loaded as low as possible in memory (via ResrvMem) so moving it high has no effect. If the code resource is not locked, and you don't plan to use the code resource for a "long" time, you should explicitly lock it and call MoveHHi prior to that. And HUnlock it when done. If you plan to use the resource for a long period of time and are not sure if the resource has the locked bit set, you should explictly call ResrvMem to get it as low as possible in the heap. +-----------------------------------------------------------------------------+ | Disclaimer: Apple has no connection with my postings. | +-----------------------------------------------------------------------------+ Byron Han, Communications Architect Cereal, anyone? :-) A1! Apple Computer, Inc. ------------------------------------- 20525 Mariani Ave, MS27Y Internet: han@apple.COM Cupertino, CA 95014 UUCP:{sun,voder,nsc,decwrl}!apple!han -------------------------------------- GENIE: BYRONHAN ATTnet: 408-974-6450 Applelink: HAN1 CompuServe: 72167,1664 ------------------------------------------------------------------------------
tim@hoptoad.uucp (Tim Maroney) (04/08/89)
In article <11817@ut-emx.UUCP> newman@ut-emx.UUCP (David Newman) writes: > >Here is another question for the net-gods: how do you call a >code resource (like an XCMD or whatever) from another piece of >code? Can it be done from a high-level language? How might it >be done in Pascal? In Pascal, you're probably going to need to link in some assembly language or at least include some INLINEs. In C, as long as the code resource follows C coding standards, you can do it all in the high level language. Get the resource and lock it down first. You then have a handle. The handle indicates a pointer. Take that pointer and convert it to a function pointer. Then call the function pointer. Here's an example in MPW C: void (*f)(); Handle res = GetResource('code', 1); if (res == 0) return; HLock(res); f = (void (*))*res; (*f)(name); And here's one in Lightspeed C, which seems to have some problems with casting things to function pointers (actually, K&R seems ambiguous on the proper syntax, so I guess we can't blame them): long (*f)(); Handle h = GetResource(TheType, TheID); if (h) { HLock(h); BlockMove(h, &f, 4); return (*f)(select, TheID, where, h, p, multi, off); } -- Tim Maroney, Consultant, Eclectic Software, sun!hoptoad!tim This message does represent the views of Eclectic Software.
oster@dewey.soe.berkeley.edu (David Phillip Oster) (04/08/89)
In article <6917@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes: >In article <11817@ut-emx.UUCP> newman@ut-emx.UUCP (David Newman) writes: >>how do you call a code resource from another piece of code? Can it be >>done from a high-level language? How might it be done in Pascal? >In Pascal, you're probably going to need to link in some assembly >language or at least include some INLINEs. Lightspeed Pascal can call other pascal functions two ways: 1.) Pascal allows the parameter of a function to be a procedure, something like: PROCEDURE foo( PROCEDURE a( Integer : b)); BEGIN a(3); END; Check your manuals for the exact syntax. If you call foo(POINTER(GetResource('MDEF', 128)^)); the POINTER() will cast the result of the GetResource()^ to a gerneric pointer that it is legal to pass to anything. Once again, watch your locking, code must be loced before you call it. >Lightspeed C, seems to have some problems with >casting things to function pointers (actually, K&R seems ambiguous on >the proper syntax, so I guess we can't blame them): I've never had any trouble casting things to function pointer in lightspeed C. But then, I always use typedefs to keep things simple enough that I can follow them. Examples: typedef void (*SubrPtr)(); typedef short (*FuncPtr)(); typedef long (*LFuncPtr)(); void CallC(f, arg)SubPtr f;Integer arg;{ (*f)(arg); } The expression ((SubrPtr) *GetResource('CDEF', 128)) is much easier to understand than (((*void)()) *GetResource('CDEF', 128)). But that only covers calling procedures that use the C calling sequence. If you are calling a function that uses the pascal calling sequence, such as a MDEF, a WDEF, or a CDEF, you can use the routines defined in teh Lightspeed C file <Pascal.h> Note, these functions are not documented in the new LightSpeed C manual. The function pointer goes _after_ all the arguments: CallPascalL(varCode, win, mesg, param, *GetResource('WDEF', 128)); for example. Once again, make sure the code resource is locked before you call it. Lightspeed Pascal probably also implements these CallPascal() functions. I don't know if Lightspeed Pascal includes a set of CallC() functions, but I'd be surprised. ------ To Tim Maroney: great pair of postings about ListManager and the usenet community. --- David Phillip Oster --"No doubt about it, time to get Arpa: oster@dewey.soe.berkeley.edu --a new signature" Uucp: {uwvax,decvax}!ucbvax!oster%dewey.soe.berkeley.edu
mnkonar@smallberries.SRC.Honeywell.COM (Murat N. Konar) (04/12/89)
In article <11817@ut-emx.UUCP> newman@ut-emx.UUCP (David Newman) writes: > >Here is another question for the net-gods: how do you call a >code resource (like an XCMD or whatever) from another piece of >code? Can it be done from a high-level language? How might it >be done in Pascal? > >Thanks, >>>Dave This code is from the Jan '89 issue of MacTutor (page 12) and it works for me (LSP 2.x) FUNCTION MyFunction (firstArg: firstType; secondArg: secondType; VAR thirdArg: thirdType; MyFunctionResource: handle) resultType; INLINE $205F, {MOVE.L (A7)+, A0} $2050, {MOVE.L (A0), A0} $4E90; {JSR (A0) } Make sure the handle to your code is locked. This code also works for procedure calls. Good Luck! ____________________________________________________________________ Have a day. :^| Murat N. Konar Honeywell Systems & Research Center, Camden, MN mnkonar@SRC.honeywell.com (internet) {umn-cs,ems,bthpyd}!srcsip!mnkonar(UUCP)