261 lines
10 KiB
Plaintext
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
|
|
|