Path: utzoo!attcan!utgpu!news-server.csri.toronto.edu!clyde.concordia.ca!uunet!samsung!usc!apple!well!oster From: oster@well.sf.ca.us (David Phillip Oster) Newsgroups: comp.sys.mac.programmer Subject: Re: Need help with XCMD's and THINK C 4.0 Message-ID: <21165@well.sf.ca.us> Date: 14 Oct 90 06:31:53 GMT References: <15784@csli.Stanford.EDU> Organization: Whole Earth 'Lectronic Link, Sausalito, CA Lines: 68 In article <15784@csli.Stanford.EDU> dmr@csli.Stanford.EDU (Daniel M. Rosenberg) writes: >We're trying to implement an XCMD in THINK C 4.0, and have followed >the examples from the "How to build XCMD's in HyperCard book" as >closely as possible. Enclosed is the root of an XFCN I wrote. It implements an interface to a proprietary file format, performaing many different functions, using the first argument as a function selector. Note the use of RememberA0(), SetUpA4(). this is critical if you use any literal strings, since THINK C references these off of its global pointer. (At least THINK C v.3 did.) Sorry about the slightly non-standard nomenclature. When I sat down to write this I discovered my Hypercard interface had succumbed to software root, so I had to reconstruct it based on the HyperCard Script Langauge Guide. This _IS_ verbatim quotes from working code that does file i/o, however. #include #include /* main - */ pascal void main(xp)XCmdPtr xp;{ RememberA0(); SetUpA4(); switch(ParamToNum(xp, 0)){ case ABVERSION: AFileVersion(xp); break; case ABOPEN: AFileOpen(xp); break; case ABCOUNTRECS: AFileCountRecs(xp); break; case ABREADFIELD: AFileReadField(xp); break; case ABCLOSE: AFileClose(xp); break; case ABREADFIELDNAME: AFileReadFieldName(xp); break; case ABCOUNTFIELDNAMES: AFileCountFieldnames(xp); break; case ABSIGNATURE: AFileSignature(xp); break; case ABMASTERID: AFileMasterID(xp); break; case ABCURRENTSORT: AFileCurrentSort(xp); break; } RestoreA4(); } #define private static typedef long LongInt; typedef short Integer; /* ParamToNum - given a parameter that should be numeric, return it. */ private LongInt ParamToNum(XCmdPtr xp, Integer n){ Str255 s; LongInt val; if(n >= xp->paramCount){ return 0; } ZeroToPas(xp, *(xp->params[n]), s); val = StrToNum(xp, s); return (xresSucc == xp->result) ? val : 0; } /* ZeroToPas - write zeroes into memory */ pascal void ZeroToPas(XCmdPtr xp, char *zeroStr, StringPtr s){ xp->inArgs[0] = (LongInt) zeroStr; xp->inArgs[1] = (LongInt) s; xp->request = xreqZeroToPas; (*xp->entryPoint)(); } -- -- David Phillip Oster - Note new signature. Old one has gone Bye Bye. -- oster@well.sf.ca.us = {backbone}!well!oster