amiga-e/amigae33a/E_v3.3a/Docs/BeginnersGuide/Modules.guide

261 lines
10 KiB
Plaintext

@database beginner.guide
@Master beginner
@Width 75
This is the AmigaGuide® file beginner.guide, produced by Makeinfo-1.55 from
the input file beginner.
@NODE "main" "Modules"
@Next "Exceptions.guide/main"
@Prev "BuiltIns.guide/main"
@Toc "Contents.guide/main"
Modules
*******
A @{fg shine }module@{fg text } is the E equivalent of a C header file and an Assembly
include file. It can contain various object and constant definitions, and
also library function offsets and library base variables. This information is
necessary for the correct use of a library.
A @{fg shine }code module@{fg text } is an extension of the module idea. As well as object
and constant definitions, a code module can contain procedures and global
variables. Code modules are like C and Assembly object files.
@{" Using Modules " Link "Using Modules" }
@{" Amiga System Modules " Link "Amiga System Modules" }
@{" Non-Standard Modules " Link "Non-Standard Modules" }
@{" Example Module Use " Link "Example Module Use" }
@{" Code Modules " Link "Code Modules" }
@ENDNODE
@NODE "Using Modules" "Using Modules"
@Next "Amiga System Modules"
@Toc "main"
Using Modules
=============
To use the definitions in a particular module you use the @{b }MODULE@{ub }
statement at the beginning of your program (before the first procedure
definition). You follow the @{b }MODULE@{ub } keyword by a comma-separated list of
strings, each of which is the filename (with path if necessary) of a
module (without the @{b }.m@{ub } extension--since every module file name must end
with @{b }.m@{ub }). The filenames (and paths) are all relative to the logical
volume @{b }Emodules:@{ub } (which can be set-up using an @{b }assign@{ub } as described in the
`Reference Manual'), unless the first character of the string is @{b }*@{ub }. In
this case the files are relative to the directory of the current source
file. For instance, the statement:
MODULE 'fred', 'dir/barney', '*mymod'
will try to load the files @{b }Emodules:fred.m@{ub }, @{b }Emodules:dir/barney.m@{ub } and
@{b }mymod.m@{ub }. If it can't find these files or they aren't proper modules the E
compiler will complain.
All the definitions in the modules included in this way are available
to every procedure in the program. To see what a module contains you can
use the @{b }showmodule@{ub } program that comes with the Amiga E distribution.
@ENDNODE
@NODE "Amiga System Modules" "Amiga System Modules"
@Next "Non-Standard Modules"
@Prev "Using Modules"
@Toc "main"
Amiga System Modules
====================
Amiga E comes with the standard Amiga system include files as E modules.
The AmigaDOS 2.04 modules are supplied with E version 2.1, and the
AmigaDOS 3.0 modules are supplied with E version 3.0. However, modules
are much more useful in E version 3.0 (see @{"Code Modules" Link "Code Modules" }). If you want to
use any of the standard Amiga libraries properly you will need to
investigate the modules for that library. The top-level @{b }.m@{ub } files in
@{b }Emodules:@{ub } contain the library function offsets, and those in directories
in @{b }Emodules:@{ub } contain constant and object definitions for the appropriate
library. For instance, the module @{b }asl@{ub } (i.e., the file @{b }Emodules:asl.m@{ub })
contains the ASL library function offsets and @{b }libraries/asl@{ub } contains the
ASL library constants and objects.
If you are going to use, say, the ASL library then you need to open the
library using the @{b }OpenLibrary@{ub } function (an Amiga system function) before
you can use any of the library functions. You also need to define the
library function offsets by using the @{b }MODULE@{ub } statement. However, the DOS,
Exec, Graphics and Intuition libraries don't need to be opened and their
function offsets are built in to E. That's why you won't find, for
example, a @{b }dos.m@{ub } file in @{b }Emodules:@{ub }. The constants and objects for these
libraries still need to be included via modules (they are not built in to
E).
@ENDNODE
@NODE "Non-Standard Modules" "Non-Standard Modules"
@Next "Example Module Use"
@Prev "Amiga System Modules"
@Toc "main"
Non-Standard Modules
====================
Several non-standard library modules are also supplied with Amiga E. To
make your own modules you need the @{b }pragma2module@{ub } and @{b }iconvert@{ub } programs.
These convert standard format C header files and Assembly include files to
modules. The C header file should contain pragmas for function offsets,
and the Assembly include file should contain constant and structure
definitions (the Assembly structures will be converted to objects).
However, unless you're trying to do really advanced things you probably
don't need to worry about any of this!
@ENDNODE
@NODE "Example Module Use" "Example Module Use"
@Next "Code Modules"
@Prev "Non-Standard Modules"
@Toc "main"
Example Module Use
==================
The gadget example program in Part Three shows how to use constants
from the module @{b }intuition/intuition@{ub } (see @{"Gadgets" Link "Examples.guide/Gadgets" }), and the IDCMP example
program shows the object @{b }gadget@{ub } from that module being used (see
@{"IDCMP Messages" Link "Examples.guide/IDCMP Messages" }). The following program uses the modules for the Reqtools
library, which is not a standard Amiga system library but a commonly used
one, and the appropriate modules are supplied with Amiga E. To run this
program, you will, of course, need the @{b }reqtools.library@{ub } in @{b }Libs:@{ub }.
MODULE 'reqtools'
PROC main()
DEF col
IF (reqtoolsbase:=OpenLibrary('reqtools.library',37))<>NIL
IF (col:=RtPaletteRequestA('Select a colour', 0,0))<>-1
RtEZRequestA('You picked colour \\d',
'I did|I can\\at remember',0,[col],0)
ENDIF
CloseLibrary(reqtoolsbase)
ELSE
WriteF('Could not open reqtools.library, version 37+\\n')
ENDIF
ENDPROC
The @{b }reqtoolsbase@{ub } variable is the library base variable for the Reqtools
library. This is defined in the module @{b }reqtools@{ub } and you @{i }must@{ui } store the
result of the @{b }OpenLibrary@{ub } call in this variable if you are going to use
any of the functions from the Reqtools library. (You can find out which
variable to use for other libraries by running the @{b }showmodule@{ub } program on
the library module.) The two functions the program uses are
@{b }RtPaletteRequestA@{ub } and @{b }RtEZRequestA@{ub }. Without the inclusion of the @{b }reqtools@{ub }
module and the setting up of the @{b }reqtoolsbase@{ub } variable you would not be
able to use these functions. In fact, if you didn't have the @{b }MODULE@{ub } line
you wouldn't even be able to compile the program because the compiler
wouldn't know where the functions came from and would complain bitterly.
Notice that the Reqtools library is closed before the program
terminates (if it had been successfully opened). This is always
necessary: if you succeed in opening a library you @{i }must@{ui } close it when
you're finished with it.
@ENDNODE
@NODE "Code Modules" "Code Modules"
@Prev "Example Module Use"
@Toc "main"
Code Modules
============
You can also make modules containing procedure definitions and some
global variables. These are called @{fg shine }code modules@{fg text } and can be extremely
useful. This section briefly outlines their construction and use. For
in-depth details see the `Reference Manual'.
Code modules can be made by using the E compiler as you would to make
an executable, except you put the statement @{b }OPT MODULE@{ub } at the start of the
code. Also, any definitions that are to be accessed from outside the
module need to be marked with the @{b }EXPORT@{ub } keyword. Alternatively, all
definitions can be exported using @{b }OPT EXPORT@{ub } at the start of the code.
You include the definitions from this module in your program using @{b }MODULE@{ub }
in the normal way.
The following code is an example of a small module:
OPT MODULE
EXPORT CONST MAX_LEN=20
EXPORT OBJECT fullname
firstname, surname
ENDOBJECT
EXPORT PROC printname(p:PTR TO fullname)
IF short(p.surname)
WriteF('Hello, \\s \\s\\n', p.firstname, p.surname)
ELSE
WriteF('Gosh, you have a long name\\n')
ENDIF
ENDPROC
PROC short(s)
RETURN StrLen(s)<MAX_LEN
ENDPROC
Everything is exported except the @{b }short@{ub } procedure. Therefore, this can be
accessed only in the module. In fact, the @{b }printname@{ub } procedure uses it
(rather artificially) to check the length of the @{b }surname@{ub }. It's not of
much use or interest apart from in the module, so that's why it isn't
exported. In effect, we've hidden the fact that @{b }printname@{ub } uses @{b }short@{ub } from
the user of the module.
Assuming the above code was compiled to module @{b }mymods/name@{ub }, here's how
it could be used:
MODULE 'mymods/name'
PROC main()
DEF fred:PTR TO fullname, bigname
fred.firstname:='Fred'
fred.surname:='Flintstone'
printname(fred)
bigname:=['Peter', 'Extremelybiglongprehistoricname']:fullname
printname(bigname)
ENDPROC
Global variables in a module are a bit more problematic than the other
kinds of definitions. You cannot initialise them in the declaration or
make them reserve chunks memory. So you can't have @{b }ARRAY@{ub }, @{b }OBJECT@{ub }, @{b }STRING@{ub }
or @{b }LIST@{ub } declarations. However, you can have pointers so this isn't a big
problem. The reason for this limitation is that exported global variables
with the same name in a module and the main program are taken to be the
same variable, and the values are shared. So you can have an array
declaration in the main program:
DEF a[80]:ARRAY OF INT
and the appropriate pointer declaration in the module:
EXPORT DEF a:PTR TO INT
The array from the main program can then be accessed in the module! For
this reason you also need to be pretty careful about the names of your
exported variables so you don't get unwanted sharing. Global variables
which are not exported are private to the module, so will not clash with
variables in the main program or other modules.
@ENDNODE