cosell@BBN-PROPHET.ARPA (Bernie Cosell) (06/21/86)
Is it possible to write C routines and have them be callable from an AmigaBasic program? I'm doing some prototyping in AmigaBasic and I'd like to be able to speed up some of the more stable cpu-intensive routines by providing C versions. I presume that if possible, it would involve some hackery like turning the C function into something that looked like a 'library' that Basic could call, but I haven't a clue how to go about all that (from either side). Any advice or examples would be appreciated. Thanks! /Bernie Bernie Cosell Internet: cosell@prophet.bbn.com Bolt, Beranek & Newman, Inc USENET: bbncc5!bpc Cambridge, MA 02238 Telco: (617) 497-3503
carolyn@cbmvax.cbm.UUCP (Carolyn Scheppner) (06/26/86)
In article <8606202331.AA05635@ucbvax.Berkeley.EDU> cosell@BBN-PROPHET.ARPA (Bernie Cosell) writes: >Is it possible to write C routines and have them be callable from >an AmigaBasic program? I'm doing some prototyping in AmigaBasic and >I'd like to be able to speed up some of the more stable cpu-intensive >routines by providing C versions. I presume that if possible, it would >involve some hackery like turning the C function into something that >looked like a 'library' that Basic could call, but I haven't a clue >how to go about all that (from either side). Any advice or examples >would be appreciated. Thanks! > A library is probably the best way. I've made a library with a couple of ml functions, made an fd file and .bmap for it, and called the functions from AmigaBasic. My next step is to add C-interface code to the library and add some functions written in C. But meanwhile, this may help you out. I am attaching 2 files. Fun.c contains a couple of specially written C functions. CFunTest is an AmigaBasic program that LoadSeg()s and CALLs the functions. ------------------------------------------------------------------------- /* Fun.c -- C functions to be LoadSeg()'d and called from another program. Compiled with no Stack checking (-v option on LC2) Linked only with Amiga.lib (no startup code) Calling program must: LoadSeg the executable file of this program. Segment ptr returned by LoadSeg * 4 + 4 = address of main() Caller must allocate a LONG variable for function result Caller calls main() passing ptr to LONG result variable Main() puts address of JumpTable in result variable Caller may then call these functions via their addresses Note that first arg for each function is address of the LONG where return value may be stashed. Also note that because these are not LIBRARY functions, they can not be DECLARED in AmigaBasic and therefore cannot return a value (since CALL must be used). Each function must be declared as void and must not attempt to return a value to AmigaBasic or stack corruption will result. Fun1 moves the screen, waits, then moves it back. Fun2 doubles the number it is passed. */ #include <exec/types.h> #include <intuition/intuition.h> extern void Fun1(), Fun2(); /* So JumpTable can be built */ typedef void (*PFV)(); PFV JumpTable[] = { Fun1, Fun2 }; /* JumpTable of function addresses */ extern ULONG AbsExecBase; ULONG SysBase; ULONG DOSBase; struct IntuitionBase *IntuitionBase; void main(resultPtr) LONG *resultPtr; { /* Set up globals SysBase and DOSBase */ SysBase = (ULONG)AbsExecBase; if ((DOSBase = (ULONG)OpenLibrary("dos.library",0))==NULL) { *resultPtr = 0; } else { CloseLibrary(DOSBase); /* We just needed the pointer */ *resultPtr = (LONG)&JumpTable[0]; } } void Fun1(resultPtr,delta) LONG *resultPtr; LONG delta; { struct Screen *frontScreen; if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))==NULL) { *resultPtr = 0; } else { frontScreen = IntuitionBase->FirstScreen; MoveScreen(frontScreen,0,delta); Delay(50); MoveScreen(frontScreen,0,-delta); CloseLibrary(IntuitionBase); *resultPtr = delta; } } void Fun2(resultPtr,arg1) LONG *resultPtr; LONG arg1; { arg1 += arg1; *resultPtr = arg1; } ---------------------------------------------------------------------------- REM - CFunTest REM - This program shows how to REM - use AmigaDOS library routines REM - to load and call specially REM - written C functions. See REM - Fun.c for more info. REM - Note 1st arg for each function REM - is address of Result& where REM - return value is stored. REM - Because non-LIBRARY functions REM - cannot be DECLAREed, they must REM - be CALLed and therefore cannot REM - directly return a value. REM *** Result& for return values *** Result& = 0 DECLARE FUNCTION LoadSeg& LIBRARY DECLARE FUNCTION IoErr& LIBRARY PRINT "Looking for dos.bmap ... "; LIBRARY "dos.library" PRINT "found it." REM *** LoadSeg the function code *** REM *** Address of InitRtn& (main) *** REM *** is (SegBptr& * 4) + 4 *** Filename$ = "Fun" Loadname$ = Filename$+CHR$(0) SegBptr& = LoadSeg&(SADD(Loadname$)) IF (SegBptr& = 0) THEN PRINT "LoadSeg of "Filename$" failed" LoadErr% = IoErr& PRINT "IO error ="LoadErr% GOTO Fcleanup2 END IF PRINT "SegBptr& = $"HEX$(SegBptr&) SegAddr& = SegBptr& * 4 PRINT "SegAddr& = $"HEX$(SegAddr&) InitRtn& = SegAddr& + 4 PRINT "InitRtn& = $"HEX$(InitRtn&) REM ***** InputLoop: INPUT "<t>ryFun or <q>uit";k$ IF k$ = "t" THEN GOSUB TryFun: GOTO InputLoop IF k$ = "q" THEN GOTO Fcleanup GOTO InputLoop TryFun: PRINT "Calling InitRtn& for address of FunctionTable" CALL InitRtn&(VARPTR(Result&)) FunTable& = Result& PRINT "Function table address = $"HEX$(FunTable&) Fun1& = PEEKL(FunTable&) Fun2& = PEEKL(FunTable& + 4) PRINT " Func 1 addr = $"HEX$(Fun1&) PRINT " Func 2 addr = $"HEX$(Fun2&) INPUT "<c>ontinue or <q>uit";k$ IF k$ <> "c" THEN GOTO SkipFun: PRINT PRINT "Fun1 moves the screen" INPUT "Press <RETURN> when ready";k$ delta& = 50 CALL Fun1&(VARPTR(Result&),delta&) PRINT "Finished Fun1&" PRINT PRINT "Fun2 doubles an integer" INPUT " Enter an integer";k$ arg1& = VAL(k$) PRINT "Argument ="arg1& CALL Fun2&(VARPTR(Result&),arg1&) PRINT "Result ="Result& PRINT "Finished Fun2&" SkipFun: RETURN Fcleanup: CALL UnLoadSeg&(SegBptr&) Fcleanup2: LIBRARY CLOSE PRINT "Done" END --------------------------------------------------------------------------- -- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Carolyn Scheppner -- CBM >>Amiga Technical Support<< UUCP ...{allegra,caip,ihnp4,seismo}!cbmvax!carolyn PHONE 215-431-9180 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=