Contents | < Browse | Browse >

|      Library mode                                                 |

   What is different ?

      > FAST environment lookup (a single instruction)

      > Immediate lists [with runtime values] are safe to use,
        even if library is used by several tasks at the same time.

      > An application may open a library several times, just
        remember to close it as many times.

   How does it work ?

      When OpenLibrary() is called on library, a new librarybase that is
      shared between the library and its opener, is created. This librarybase
      contains the jump/func-table and the global e-environment needed for
      each opener. There is no 32k limit on this environment as is usual with
      other similar solutions. If the same task does OpenLibrary() on our
      library several times, the same librarybase will be returned as from the
      first call.

   Usage is pretty much like with AmigaE, but keep this in mind:

      The main() routine (if defined) should return <>NIL if all went okay,
      else FALSE. Returning FALSE will make OpenLibrary() to fail.

      The "LIBRARY ..." declaration must be placed before
      any "RAISE", "DEF", "PROC", "label:".

   The private librarybase

      A pointer to the librarybase can be obtained through the
      global "librarybase" variable. This is not the librarybase
      in execbase.liblist, but the one the application using the
      library has obtained.

      The 18 bytes after the standard library header of this base
      is free to use in any way by the library/application.
      You should have GOOD reasons to use this area, else don't do it.
      An example of use would be plugin-libraries for GoldED (Dietmar Eilert),
      that needs to have a special binary ID poked into offset
      36 of the librarybase. This would be done in the main()

      librarybase.version is a bit special, it contains the version requested
      by OpenLibrary(), not necessarily the actual version of your library.
      This might be handy if you need to do different stuff depending on
      the version.. but you probably should not do it :)


      Using "EMPTY" instead of a procedure name in the list of entries
      creates a dummy function that just returns NIL.

      In powerpc mode for morphos, the library will by default have a 68k
      ABI, which will be callable from 68k programs. You should define the
      registers used for arguments and not let the compiler decide, because
      ECX and EC/CreativE uses different defaults. And it makes things more

      Using the "SYSV" switch will create a library with MorphOS SYSV
      ABI. This is faster, but cannot be called from 68K programs anymore.
      Like this:

         OPT POWERPC
         LIBRARY SYSV name,ver,rev,idstr IS ...

      A MorphOS 2.0+ library may define a "query" function at the offset of
      the normally unused "ExtFunc" (offset -24), it should look something
      like this:

      (Note: we have no global environment inside query() function!
       For this reason "utilitybase" (needed by FindTagItem()) is passed to
       it so that we do not have to open and close it everytime ourselves.)

      PROC query(data:PTR TO LONG, attr, utilitybase)
         DEF ti:PTR TO tagitem
         IF ti := FindTagItem(attr, mytags)
            data[] :=
            RETURN TRUE
            RETURN FALSE

      A MorphOS 2.0+ library may use an extended resident structure containing
      tags. Example:

      LIBRARY 'bla.library', 50, 1, 'bla.library by nisse 2007' TAGS mytags IS

           TAG_YYY, VAL_YYY,


      Finally, it should also be noted that with ECX it is possible to create
      your library or even device "by hand". Just use OPT NOSTARTUP at the top
      of your source and.. well that is beyond the scope of this guide.