Xref: utzoo comp.sys.amiga:45784 comp.sys.amiga.tech:8892 Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!cbmvax!peter From: peter@cbmvax.commodore.com (Peter Cherna) Newsgroups: comp.sys.amiga,comp.sys.amiga.tech Subject: Re: Making shared libraries (was: Lattice blink question) Message-ID: <9039@cbmvax.commodore.com> Date: 15 Dec 89 22:33:24 GMT References: <596@cameron.cs.duke.edu> <1989Dec15.042112.9582@aucs.uucp> Reply-To: peter@cbmvax.commodore.com (Peter Cherna) Followup-To: comp.sys.amiga.tech Organization: Commodore, West Chester, PA Lines: 111 In article <1989Dec15.042112.9582@aucs.uucp> 840445m@aucs.UUCP (Alan McKay) writes: >In article <596@cameron.cs.duke.edu> amr@dukee.egr.duke.edu (Anthony M. Richardson) writes: >>I've always thought the Amiga shared libraries were a nifty idea and >>so I've decided to try and create my own library. Blink (with thei >> >>Tony Richardson amr@dukee.egr.duke.edu > >Try 'oml' which comes with Lattice 5.0x. It is used specifically for >making shared libraries. >-- >+ Alan W. McKay + VOICE: (902) 542-1565 + >+ Acadia University + "Courage my friend, it is not yet too late + >+ WOLFVILLE, N.S. + to make the world a better place." + >+ 840445m@AcadiaU.CA + - Tommy Douglas + Actually, oml is for making linked libraries, which may indeed by shared _at_compile_time_. Things like lc.lib, amiga.lib, and others are like this. However, I believe Anthony is talking about making Amiga shared libraries that live in libs:. There are new support features as of the 5.04 release of Lattice that help make this easy. Your C source modules must be compiled with the -ml switch. If you have a function foo that takes an int and a long *, and returns a char *, you would declare it like char * __saveds __asm LIB_foo(register __d0 int i, register __a0 long *lptr) The __saveds instructs Lattice to set up your data area (off A4) when anybody calls your function. The __asm keyword states that you intend to specify which registers receive which parameters, as shown above. The 'LIB_' is any prefix you care to associate with the actual names of the functions. You must also provide this prefix to blink. If you wish from within your library to call one of your public functions through the function table, you just do so, as in: cptr = foo(i, lptr) In highly exceptional circumstances, you may wish to call yourself directly (not through the table). Then use cptr = LIB_foo(i, lptr) Note that if someone SetFunctions() your library, only the former type of call are affected. You will also have to create an "fd" file, which typically looks like ##base MyLibBase ##bias 30 foo(i,lptr)(D0/A0) ... ##end The ##base directive names the library base that clients of your library will need. The ##bias directive gives the offset to the first of your functions (for a library, it is 30). Your functions follow, with the parameters named in brackets, and the registers after. Registers are separated by "/" or by ",". Use "/" when in correct order for multiple moves (An/Am or Dn/Dm are ok if n < m, An/Dm is always ok, Dm with An must use a comma, i.e. Dm,An). Lattice's fd2pragma utility will build a pragma file you can include so that clients may call your routines. They'll have to declare struct Library *MyLibBase and call OpenLibrary() to get it. The declaration must precede the #include of your pragma file. In order to call yourself through the library jump table, you must also include this file. Your own library base will be in A6, so you should #define MyLibBase (struct Library *)getreg(REG_A6) When you link, you must link with Lattice's libent.o first, libinit.c second, and your .o files after. As well, you provide LIBPREFIX _LIB_ (or whatever you chose, but you'll need a leading underscore here), and LIBFD mylib.fd (your fd file). Also, you may use what look like global variables, and Lattice arranges to stuff them off your library base. In the source to libinit.c, they imply you can initialize stuff at the appropriate moment. Well, a warning: DO NOT INITIALIZE ANY OF YOUR GLOBALS IN LIBINIT.C. If you need to do stuff upon open, add a call to some MyOpenFunc() inside LibOpen(), and put that function in a module other than libinit.c. If you need stuff in your library base to be public, you'll have to extend the MyLibrary structure in libinit.c, and figure out how to access it. Any globals that Lattice cares for you automatically are placed whereever Lattice feels, and could change as you change your source. You should end up with a shared library. Hope this helps. -- Peter Cherna, Software Engineer, Commodore-Amiga, Inc. {uunet|rutgers}!cbmvax!peter peter@cbmvax.cbm.commodore.com My opinions do not necessarily represent the opinions of my employer. "A friend of mine is into Voodoo Acupuncture. You don't have to go. You'll just be walking down the street and ..... oooohhh, that's much better..." - Steven Wright