-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhtdll.html
189 lines (177 loc) · 8.66 KB
/
htdll.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Breaking the 64KB Limit Using a DLL</TITLE>
<STYLE TYPE="TEXT/CSS">
<!--
.IE3-DUMMY { CONT-SIZE: 100%; }
BODY { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; BACKGROUND-COLOR: #E0E0E0; }
P { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H1 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H2 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H3 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H4 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H5 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
H6 { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
UL { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; }
TD { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; BACKGROUND-COLOR: #FFFFFF; }
.NOBORDER { BACKGROUND-COLOR: #E0E0E0; PADDING: 0pt; }
.NOBORDER TD { FONT-FAMILY: Verdana,Arial,Helvetica,Sans-Serif; BACKGROUND-COLOR: #E0E0E0; PADDING: 0pt; }
.CODE { FONT-FAMILY: Courier New; }
-->
</STYLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#E0E0E0">
<FONT SIZE="5"><B>Breaking the 64KB Limit Using a DLL</B></FONT>
<HR>
<P>Breaking the 64 KB limit is an important topic, and because of the internal
representation of files in the AMS as well as the size limit of memory
blocks, it is possible only by breaking the program up into multiple files.
<BR><BR>
If you get close to this limit, the first thing to do is optimizing the
program. Ways to do this are those described in
<A HREF="httigcc.html#advanced">Advanced Options of GCC4TI</A>, using functions from the AMS instead of
those from the GCC4TI Library, and, last but not least, hand-optimizing the
code. If and only if you are still close to the limit, you should think about
the possibility to use multiple files. At first, try storing as much data as
possible (sprites, maps, etc.) in external files (using functions from
<A HREF="vat.html">vat.h</A>). If this still does not help, the only
possibility left is to split the code into multiple files.
<BR><BR>
This means that you need to use some form of dynamic link libraries. These
are very well-known for kernel programs, but kernel-mode libraries are not
something we want to encourage, seeing that they have led to a huge mess of
versioning problems and incompatiblities. For information about how to create
them, see the section <A HREF="httigcc.html#kernel">How to make
kernel-based programs</A>. The necessary definitions for libraries for
kernel-less programs can be found in the <A HREF="dll.html">dll.h</A>
header file.
<BR><BR>
Now that we have explained why you might need to use external libraries, we
specifically want to discourage their use for anything else. External
(dynamic) libraries have been used quite often in the past to automate common
tasks, like file access, graphics, compression, etc. This is <I>not</I> what
we want to happen, otherwise there will be a different libraries for the same
tasks, with a lot of incompatiblities between libraries and even between
different versions of the same library. GCC4TI provides the possibility to use
static libraries (also known as function archives) for this purpose. In the
<A HREF="ide.html">IDE</A>, you need to select the creation of a
function archive in the project options; when using the
<A HREF="comopts.html#SEC3">command line compiler</A>, you need to use
the <B>'-ar'</B> switch. When using function archives, only the files which
are needed are really included in the final program.
<BR><BR>
There is an exception to the rule that you should not create a dynamic
library to make it available to others: If the library itself is very large,
and a program will typically use a lot of its functions at the same time,
client programs are likely to exceed the file size limit if it is provided as
a static library. In this case, using a dynamic library really is the only
possibility. An example is the FAT Library by the
<A HREF="http://tict.ticalc.org/">TI-Chess Team</A>.
<BR><BR>
Hopefully, we have talked you out of creating a dynamic library if there is
any other reasonable option. Now we can explain how to create a dynamic
library in nostub (kernel-less) mode. For detailed explanations of all
directives, take a look at the <A HREF="dll.html">dll.h</A> header
file. The "Custom DLL" example demonstrates the creation of a very small
library (note that the library file must have the name "mydll" on the
calculator):</P>
<PRE>// Custom DLL example; must be named "mydll"
// Note: You should not use DLLs under normal circumstances; see section
// "How to break the 64 KB limit using a DLL" for more information.
#define USE_TI89
#include <tigcclib.h>
DLL_INTERFACE
char MessageInDLL[]="Hello!\n";
long GlobalVarInDLL;
void HelloFromDLL(void);
int SumFromDLL(int,int);
DLL_ID 372377271
DLL_VERSION 2,12
DLL_EXPORTS HelloFromDLL,SumFromDLL,MessageInDLL,&GlobalVarInDLL
DLL_IMPLEMENTATION
void HelloFromDLL(void)
{
printf ("Hello from DLL!\n");
printf ("Global variable is %ld\n", GlobalVarInDLL);
}
int SumFromDLL(int a, int b)
{
return (a + b);
}
</PRE>
<P>The order of the definitions is very important; read more about this in
<A HREF="dll.html#DLL_INTERFACE">DLL_INTERFACE</A>. The exported symbols
are <I>HelloFromDLL</I>, <I>SumFromDLL</I>, <I>MessageInDLL</I>, and
<I>GlobalVarInDLL</I>; they are assigned index numbers from 0 to 3.
<BR><BR>
A client program which uses this DLL could look like the following example,
called "Custom DLL Test":</P>
<PRE>#define USE_TI89
#include <tigcclib.h>
#define HelloFromDLL _DLL_call(void,(void),0)
#define SumFromDLL _DLL_call_attr(int,(int,int),__attribute__((stkparm)),1)
#define MessageInDLL _DLL_reference(const char,2)
#define GlobalVarInDLL _DLL_glbvar(long,3)
void _main(void)
{
if (LoadDLL ("mydll", 372377271, 2, 11) != DLL_OK)
{
DlgMessage ("ERROR", "Error loading DLL!", BT_OK, BT_NONE);
return;
}
clrscr ();
GlobalVarInDLL = 1234567;
HelloFromDLL ();
printf ("Sum from DLL: 2+3=%d\n", SumFromDLL (2, 3));
printf ("Message from DLL: %s\n", MessageInDLL);
ngetchx ();
UnloadDLL ();
}
</PRE>
<P>This program simply demonstrates all possible ways to import symbols from the
DLL. See <A HREF="dll.html#LoadDLL">LoadDLL</A> and the corresponding
identifiers for more information.
<BR><BR>
A program which wants to use DLLs has to be executing from the so-called
"ghost address space". This means that the program either has to be started
through an external launcher which calls
<A HREF="system.html#enter_ghost_space">enter_ghost_space</A> (which is
always the case if it is exe-packed), or
<CODE><A HREF="httigcc.html#advanced_ghostspace">EXECUTE_IN_GHOST_SPACE</A></CODE>
needs to be defined at the beginning of the program. You will will want to
exepack the program anyway if it is large enough. In the
<A HREF="ide.html">IDE</A>, this can be done through a check box in
the project options; when using the
<A HREF="comopts.html#SEC3">command line compiler</A>, you need to use
the <B>'-pack'</B> switch.
<BR><BR>
Note that this example is an exception to the rules above. It breaks two
rules: First, it does not even come close to the 64 KB limit. Second, there
is a variable in the DLL that could be put in another file: MessageInDLL.
This program should remain the <I>only</I> exception; it only exists because
a small program is best to teach. Imagine trying to learn how to use a DLL
from a program that pushed the 64 KB limit (several thousand lines of code)!
<BR><BR>
Certain pseudo-constants in <A HREF="compat.html">compat.h</A> depend
on initialization code, which is not present at all in DLLs. Using
definitions like
<CODE><A HREF="httigcc.html#advanced_calcdetect">NO_CALC_DETECT</A></CODE> helps
for calculator-dependent definitions, but not all parts of the GCC4TI Library
are available (for example, defining
<CODE><A HREF="htretval.html">RETURN_VALUE</A></CODE> makes
absolutely no sense).
<BR><BR>
Finally, we need to write a few sentences about DLL version information. The
major version number needs to be changed if and only if two DLLs are
incompatible with each other. Adding new functions does not make DLLs
incompatible; rearranging them does, for example. Usually, you do not ever
need to change the major version number. Increasing the minor version number
means that the DLL is still compatible with existing programs; the client
program can specify a minimum minor version number to indicate that it
depends on the new functionality.</P>
<P>See also: <A HREF="dll.html">dll.h</A></P>
<HR>
<H3><A HREF="index.html">Return to the main index</A></H3>
</BODY>
</HTML>