•  Back 
  •  Shared libraries 
  •  Index 
  •  Tree View 
  •  Cross references 
  •  Help page 
  •  Show info about hypertext 
  •  View a new file 
Topic       : TOS - The Operating System
Author      : 
Version     : tos.hyp (December 19, 2008)
Subject     : Programmieren/Atari
Nodes       : 3010
Index Size  : 93790
HCP-Version : 5
Compiled on : Atari
@charset    : atarist
@lang       : 
@default    : Title
@help       : 
@options    : +g -i -s +x +zz -t4
@width      : 70
View Ref-File11.5.18.4  How do I write a library?                               TOS

For this too there is a sample library SLB_DEMO, which contains all 
the required elements and descriptions. The best thing is to copy 
SLB_DEMO.C, LIBHEAD.S and SLB_DEMO.PRJ and then modify the files to 
suit your requirements. It is most important to ensure that bit 3 of 
the flag in the program header of a library is set; one can use 
PH_BIT3.TTP for this.

LIBHEAD is the header for a shared library. The pointer to the 
function names can be omitted, otherwise it points to a table of 
pointers with the names of the library functions. The number of 
functions must be stated correctly, as must the table of functions and 
the library name, which is identical to the filename. When adding a 
function one has to ensure that the function number is adapted 
accordingly, and perhaps that the version number is increased.

For publicly available shared libraries one has to ensure that 
documented function calls are never altered! They can either be 
supplemented with new parameters (the called function can inquire the 
number of parameters actually passed), or a new function number should 
be used.

NULL-pointers are also permissible for the function pointers; they 
return a EINVFN when the function is called.

The following functions for (de-)initialization are obligatory:

slb_init/slb_exit

These are called during loading and removal of the library 
respectively, and at that in supervisor-mode and in the context 
(process) of the library. Typically, slb_init loads a configuration 
file, allocates global memory for the library and opens a virtual VDI 
workstation. slb_exit writes back the configuration file, releases the 
memory again and closes the VDI workstation.

If slb_init opens a file, then the handle can only be accessed again 
at slb_exit, as all other calls of the library run in the context of 
the calling application.

From MagiC 6 onwards the library is passed a normal 'C' character 
string in the command line structure which contains the complete path 
of the shared library. If the shared library has to load configuration 
or RSC files, the path can be extracted and the filename of the 
configuration file assembled correspondingly.

If slb_init terminates by reason of a bus error, for instance, then 
the caller will get EXCPT as the result of the Slbopen call. In order 
to intercept an unplanned termination of the library, the kernel 
installs an etv_term handler for the library before calling 
slb_init/exit.

slb_open/slb_close

These are called at the opening or closing of the library 
respectively. Once the library has been opened, the order is:

  slb_init
  slb_open
  slb_close
  slb_exit

Unlike slb_init/slb_exit, slb_open/slb_close run in the context of the 
caller and in user-mode, with the user-stack of the caller, even if 
the Slbopen call was performed in supervisor-mode.

The library can also allocate memory at slb_open, though this belongs 
to the caller and should be released again at slb_close. In order to 
permit allocation of this reserved memory to the caller, the library 
is also passed the current process descriptor at slb_open, slb_close 
and at every function call.

Warning: Due to a bug in 5.20, the passing of the PD to slb_open and 
slb_close only works from MagiC 6 onwards.

The kernel ensures that the open/close calls are nested correctly, 
i.e. a process can not open a library more than once.

The kernel ensures that the open/close calls are nested correctly, 
i.e. a process cannot open a library more than once.

Functions

Functions are not obligatory, so a library can hook in system calls 
also via the AES or DOS that are removed again at termination, yet 
generally functions are made available.

A function is called with the following parameters on the stack:

 PD *pd       Process descriptor of the caller, corresponds to the 
              associated slb_open()/close()
 LONG fn      Function number. Practical when several functions are 
              amalgamated (identical function pointers in LIBHEAD)
 WORD nargs   Number of the following arguments, in WORDs. If a 
              function has a variable number of parameters, one can 
              ascertain the actual number. Very useful for extensions, 
              without having to incorporate new functions. Example: If 
              a function always expects a pointer, but optionally also 
              a WORD, it will receive either 2 or 3 as nargs.
 ...          The remaining parameters

The functions are executed in the context of the caller and with its 
stack. As this call is generally made in user-mode, multitasking will 
not be interrupted even for longer operations. Depending on the 
function, the function result can be a LONG, a WORD, void etc.

A function may alter registers d0-d2 and a0-a1, all other registers 
have to be saved if appropriate. In particular, register a2 must not 
be altered, so that Pure-C routines may be called.