home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
disks
/
disk393.lzh
/
LibTool
/
CSimple
/
SimpleC.DOC
< prev
next >
Wrap
Text File
|
1990-10-28
|
9KB
|
160 lines
This document describes how to make the simple.library C example.
A shared library is a disk-based executable file that usually resides in
the LIBS drawer of your boot disk. Such a library contains functions that
your application can call, but which are not a part of your program. Many
other applications can open and use the same shared library (usually simul-
taneously), thus saving memory when the applications are run concurrently.
Also, a shared library can help reduce development time in new products since
you can make a library of commonly used routines, and just open and use it
for each program that you write. There's no need to scavange old code, re-
compile or re-assemble previously written functions, modify code to avoid
conflicting labels and variable names, or re-edit old INCLUDE files. Also,
you can allow other programmers to make use of your libraries without having
to give away source code or object modules of the functions.
The first step in making a shared library is to write and test the functions
which you intend to put in the library. The easiest way to do this is to
develop a self-contained program to test the functions. When you are finished
modifying the functions and are certain that they work properly, separate them
from the rest of the code along with their variables. When writing lib
functions, it is best to avoid using global variables. Use locals or allocate
mem as needed. This will make your library truly reentrant (many tasks can use
it simultaneously without stomping on each other's variables). The only globals
in your lib code should be pre-initialized variables which never change value
(such as an error message string). Place these functions in their own ascii
text file. Save the remainder of your test program since this will be turned
into a test application to open and use the new library.
The text file, "Simple.c", is an example of this. I created 3 routines,
Add2Numbers, Sub2Numbers, and Mult2Numbers which I wish to turn into a shared
library.
In order to turn these functions into a library, I need to create two more
files: an fd file which describes what args are passed to the functions in
which regs, and a library startup code to be linked with these functions.
"SimpleC.fd" is an example of an fd file. Here is the contents of that file:
##base SimpleBase *the name of our base used by C glue code and C PRAGMAS
##name simple *the name of our library (i.e. simple.library)
##vers 1 *version #
##revs 0 *revision #
##libid simple C lib (ver 1.0)
##bias 30 *first function is always at an offset of -30 from lib base
*Here are all of the lib functions callable by an application
*All 3 functions return ULONG
##ret ULONG
Add2Numbers(num1,num2)
Sub2Numbers(num1,num2)
Mult2Numbers(num1,num2)
##end
Note that some of the lines begin with ##. This indicates that this line is
a command. The command follows the ##.
For example, the first line begins with ##base. This means that the label
following ##base is the variable which is used in C glue stubs for our library.
I have chosen to name this variable SimpleBase. This is the name of the global
variable you must declare in your application, and is where you store the
returned lib base from OpenLibrary(). A good naming method is to append "Base"
to the name of your library. Thus, we come up with SimpleBase for this example.
Your application will then do the following:
struct SimpleBase *SimpleBase = 0L;
SimpleBase = (struct SimpleBase *) OpenLibrary("simple.library", 0L)
Note that if you take advantage of LibTool's C Include file making capability,
the above code will automatically be created for you.
The next line starts with ##name. This means that the following label is what
we intend to call our library (minus the .library extension). So, our library
is going to be named "simple.library".
The next line, ##vers, indicates what the version of our library is. This
number is what an application uses when it opens our library.
The next line, ##revs, is the revision number of our library. This should be
incremented everytime we make a new library which is backwardly compatible with
an earlier library, but somehow different.
The next line, ##libid, is a string which describes our library. This can be
anything you choose, but should include the name of the library and version
and revision. Note that I chose "simple C lib (ver 1.0)" for this string.
The 1.0 means version 1, revision 0.
The next line, ##bias, indicates the negative offset from the library base
for its first custom function. This should always be 30 for our purposes.
The next line, ##ret describes what the following function(s) return. For
example, all 3 functions return ULONG. If I happened to have a fourth function,
Blort() which returned a struct Window *, I would have to add a ##ret before
Blort's function definition as so:
##ret struct Window *
Blort()
The next 3 lines are the descriptions of my 3 library functions. The order
of these is arbitrary. Note that I have the name of the function and its input
args in parenthesis. The args are being passed on the stack since our lib is
written in C. If a function doesn't require any input args, then I would only
need 1 set of empty parenthesis. For example,
NoArgsFunc()
The last line, ##end, just means that this is the end of the fd file.
You must create this fd file yourself. This file is then used by the LibTool
program to create almost all of the other files needed for this project.
Now, let's make our simple.library. First, compile and assemble the 3
functions (Simple.c) into a resulting object file, Simple.o. For Manx, make
sure that you compile with +b to eliminate the .begin statement. LibTool will
generate the proper startup code for us. Use LARGE CODE, LARGE DATA for this
example lib. Thats -b0 for Lattice and +p for Manx. If you use SMALL CODE/DATA,
then every callable lib function would have to setup its data base reg (usually
a4) at the start, and upon return, restore that reg. Consult your C manual for
directions.
Next, invoke LibTool.
LibTool -cmho glue.asm SimpleC.fd
The -c option tells LibTool that our lib is written in C and consequently
expects an application to pass args on the stack (not in 68000 regs as is
normally the case). The glue stubs or PRAGMAS which are created will adjust for
args expected on the stack. The -h option means to make a C INCLUDE file for
our test application. The -m option means to make the startup code for our
library functions. The -o glue.asm means to make 1 file with all of the glue
stubs in it instead of separate files for each function. We won't use PRAGMAS
for this example.
This will make 3 files, "glue.asm", "SimpleC.h", and "SimpleC.src". "glue.asm"
is the glue code that will be linked with our C application. "SimpleC.src" is
the asm code which gets linked with our 3 functions and turns them into a
shared library. "SimpleC.h" is the C include file for our test application.
Assemble "SimpleC.src" into a resulting object called "libstart.o". Now you must
link the files. ALWAYS LINK THE SRC MODULE MADE BY LIBTOOL FIRST. For example,
blink libstart.o simple.o LIB lib:lcnb.lib NODEBUG TO libs:simple.library
ln -o libs:simple.library libstart.o simple.o -lcl32
Note that we do not need the standard startup code "lib:c.o". For Manx, you
need to specify the +b option when compiling to get rid of the .begin statement.
We have now made our shared library and placed it in the LIBS: drawer as
"simple.library".
This is the method you use to make any shared library.
Now let's make a C application to test the library. "SimpleCApp.c" is
an example of this. Compile and assemble this file. Link it with any standard
startup code (not libstart.o!!!). LibTool already made our glue file and
INCLUDE file. Note that the INCLUDE file has two functions in it, OpenSimpleBase
and CloseSimpleBase. It also declares SimpleBase. These functions allow you
to easily open and close the new library. The name of the functions are created
by appending the lib base name (declared in the fd file) to "Open" and "Close".
Simply open the library by calling OpenSimpleBase(). If this returns TRUE, then
the library opened. Later, you can close the library with CloseSimpleBase. The
INCLUDE file also declares all of the lib functions as extern.
blink lib:c.o SimpleCApp.o glue.o LIB lib:lcnb.lib NODEBUG TO ram:TestProgram
ln -o ram:TestProgram SimpleCApp.o glue.o -lcl32
Now run ram:TestProgram and see how the application uses simple.library.
Here's how to make a PRAGMA file, "Simple.pragma", for the Lattice C compiler
LibTool -lp SimpleC.fd
After experimenting with creating a few of your own simple libraries, study
the CComplex example which demonstrates a few more complicated considerations
in constructing a library.