]> gitweb.factorcode.org Git - factor.git/blob - doc/handbook/alien.facts
e45cb97d8576195a7ee1a8c1fa5eb2aeab8c3f1d
[factor.git] / doc / handbook / alien.facts
1 IN: alien
2 USING: arrays errors help libc math ;
3
4 ARTICLE: "alien" "C library interface"
5 "Factor can directly call C functions in native libraries. It is also possible to compile callbacks which run Factor code, and pass them to native libraries as function pointers."
6 $terpri
7 "The C library interface is entirely self-contained; there is no C code which one must write in order to wrap a library."
8 $terpri
9 "C library interface words are found in the " { $vocab-link "alien" } " vocabulary."
10 { $warning "Since C does not retain runtime type information or do any kind of runtime type checking, any C library interface is not pointer safe. Improper use of C functions can crash the runtime or corrupt memory in unpredictible ways." }
11 { $subsection "loading-libs" }
12 { $subsection "alien-invoke" }
13 { $subsection "alien-callback" }
14 { $subsection "c-types" }
15 { $subsection "c-objects" }
16 { $subsection "malloc" }
17 { $subsection "dll-internals" } ;
18
19 ARTICLE: "loading-libs" "Loading native libraries"
20 "Before calling a C library, you must associate its path name on disk with a logical name which Factor uses to identify the library:"
21 { $subsection add-library }
22 "Once a library has been defined, you can try loading it to see if the path name is correct:"
23 { $subsection load-library } ;
24
25 ARTICLE: "alien-invoke" "Calling C from Factor"
26 "The easiest way to call into a C library is to define bindings using a pair of parsing words:"
27 { $subsection POSTPONE: LIBRARY: }
28 { $subsection POSTPONE: FUNCTION: }
29 "Don't forget to compile your binding word after defining it; C library calls cannot be made from an interpreted definition."
30 $terpri
31 "The above parsing words create word definitions which call a lower-level word; you can use it directly, too:"
32 { $subsection alien-invoke }
33 "Sometimes it is necessary to invoke a C function pointer, rather than a named C function:"
34 { $subsection alien-indirect }
35 "There are some details concerning the conversion of Factor objects to C values, and vice versa. See " { $link "c-types" } "." ;
36
37 ARTICLE: "alien-callback" "Calling Factor from C"
38 "Callbacks can be defined and passed to C code as function pointers; the C code can then invoke the callback and run Factor code:"
39 { $subsection alien-callback }
40 "There are some details concerning the conversion of Factor objects to C values, and vice versa. See " { $link "c-types" } "." ;
41
42 ARTICLE: "c-types" "C types"
43 "The " { $link POSTPONE: FUNCTION: } ", " { $link alien-invoke } " and " { $link alien-callback } " words convert Factor objects to and from C values."
44 $terpri
45 "The C library interface can handle a variety of native data types. C types are identified by strings, and a few utility words are defined for working with them:"
46 { $subsection c-type }
47 { $subsection c-size }
48 { $subsection c-align }
49 "Support for a number of C types is built-in:"
50 { $subsection "c-types-numeric" }
51 { $subsection "c-types-pointers" }
52 { $subsection "c-types-strings" }
53 "New C types can be defined using facilities which resemble C language features:"
54 { $subsection "c-structs" }
55 { $subsection "c-unions" } ;
56
57 ARTICLE: "c-types-numeric" "Integer and floating point C types"
58 "The following numerical types are available; a " { $snippet "u" } " prefix denotes an unsigned type:"
59 { $table
60     { "C type" "Notes" }
61     { { $snippet "char" } "always 1 byte" }
62     { $snippet "uchar" }
63     { { $snippet "short" } "always 2 bytes" }
64     { $snippet "ushort" }
65     { { $snippet "int" } "always 4 bytes" }
66     { $snippet "uint" }
67     { { $snippet "long" } { "same size as CPU word size and " { $snippet "void*" } ", except on 64-bit Windows, where it is 4 bytes" } }
68     { { $snippet "ulong" } { } }
69     { { $snippet "longlong" } "always 8 bytes" }
70     { { $snippet "ulonglong" } { } }
71     { { $snippet "float" } { } }
72     { { $snippet "double" } "same format as " { $link float } " objects" }
73 }
74 "When making alien calls, Factor numbers are converted to and from the above types in a canonical way. Converting a Factor number to a C value may result in a loss of precision."
75 $terpri
76 "Numerical values can be read from memory addresses and converted to Factor objects using the various typed memory accessor words:"
77 { $subsection alien-signed-1 }
78 { $subsection alien-unsigned-1 }
79 { $subsection alien-signed-2 }
80 { $subsection alien-unsigned-2 }
81 { $subsection alien-signed-4 }
82 { $subsection alien-unsigned-4 }
83 { $subsection alien-signed-cell }
84 { $subsection alien-unsigned-cell }
85 { $subsection alien-signed-8 }
86 { $subsection alien-unsigned-8 }
87 { $subsection alien-float }
88 { $subsection alien-double }
89 "Factor numbers can also be converted to C values and stored to memory:"
90 { $subsection set-alien-signed-1 }
91 { $subsection set-alien-unsigned-1 }
92 { $subsection set-alien-signed-2 }
93 { $subsection set-alien-unsigned-2 }
94 { $subsection set-alien-signed-4 }
95 { $subsection set-alien-unsigned-4 }
96 { $subsection set-alien-signed-cell }
97 { $subsection set-alien-unsigned-cell }
98 { $subsection set-alien-signed-8 }
99 { $subsection set-alien-unsigned-8 }
100 { $subsection set-alien-float }
101 { $subsection set-alien-double } ;
102
103 ARTICLE: "c-types-pointers" "C pointer types"
104 "Every C type always has a corresponding pointer type whose name is suffixed by " { $snippet "*" } "; at the implementation level, all pointer types are equivalent to " { $snippet "void*" } "."
105 $terpri
106 "The Factor objects which can be converted to " { $snippet "void*" } " form a class:"
107 { $subsection c-ptr }
108 { $warning "Since byte arrays can move in the Factor heap, make sure to only pass a byte array to a C function expecting a pointer if you know the function will not retain the pointer after it returns. If you need permanent space for data which must not move, see " { $link "malloc" } "." }
109 "C " { $snippet "void*" } " value returned by functions are wrapped inside fresh " { $link alien } " objects." ;
110
111 ARTICLE: "c-types-strings" "C string types"
112 "The C library interface defines two types of C strings:"
113 { $table
114     { "C type" "Notes" }
115     { { $snippet "char*" } "8-bit per character null-terminated ASCII" }
116     { { $snippet "ushort*" } "16-bit per character null-terminated UTF16" }
117 }
118 "Passing a Factor string to a C function expecting a C string allocates a byte array in the Factor heap; the string is then converted to the requested format and a raw pointer is passed to the function. If the conversion fails, for example if the string contains null bytes or characters with values higher than 255, a " { $link c-string-error. } " is thrown."
119 $terpri
120 "C functions must not retain such pointers to heap-allocated strings after returning, since byte arrays in the Factor heap can be moved by the garbage collector. To allocate a string which will not move, use " { $link <malloc-string> } " and then " { $link free } "."
121 $terpri
122 "A couple of words can be used to read and write " { $snippet "char*" } " and " { $snippet "ushort*" } " strings from arbitrary addresses:"
123 { $subsection alien>char-string }
124 { $subsection alien>u16-string }
125 { $subsection string>char-alien }
126 { $subsection string>u16-alien } ;
127
128 ARTICLE: "c-structs" "C structure types"
129 "A " { $snippet "struct" } " in C is essentially a block of memory with the value of each structure field stored at a fixed offset. The C library interface provides some utilities to define words which read and write structure fields given a base address."
130 { $subsection POSTPONE: BEGIN-STRUCT: }
131 { $subsection POSTPONE: FIELD: }
132 { $subsection POSTPONE: END-STRUCT }
133 "Great care must be taken when working with C structures since no type or bounds checking is possible."
134 $terpri
135 "An example:"
136 { $code
137     "BEGIN-STRUCT: surface"
138     "    FIELD: uint    flags"
139     "    FIELD: format* format"
140     "    FIELD: int     w"
141     "    FIELD: int     h"
142     "    FIELD: ushort  pitch"
143     "    FIELD: void*   pixels"
144     "    FIELD: int     offset"
145     "    FIELD: void*   hwdata"
146     "    FIELD: short   clip-x"
147     "    FIELD: short   clip-y"
148     "    FIELD: ushort  clip-w"
149     "    FIELD: ushort  clip-h"
150     "    FIELD: uint    unused1"
151     "    FIELD: uint    locked"
152     "    FIELD: int     map"
153     "    FIELD: uint    format_version"
154     "    FIELD: int     refcount"
155     "END-STRUCT"
156 }
157 "When calling a C function expecting a structure as input, use a utility word which allocates a byte array of the correct size:"
158 { $subsection <c-object> }
159 "To learn how to allocate an unmanaged block from the operating system suitable for holding a C structure, see " { $link "malloc" } "."
160 $terpri
161 "You can test if a C type is a structure type:"
162 { $subsection c-struct? } ;
163
164 ARTICLE: "c-unions" "C unions"
165 "A " { $snippet "union" } " in C defines a type large enough to hold its largest member. This is usually used to allocate a block of memory which can hold one of several types of values."
166 { $subsection POSTPONE: C-UNION: } ;
167
168 ARTICLE: "c-objects" "C objects"
169 "Alien address objects can be constructed and manipulated directly:"
170 { $subsection <alien> }
171 { $subsection <displaced-alien> }
172 { $subsection alien-address }
173 { $subsection expired? }
174 "There are various ways to abstract the pointer manipulation associated with C arrays and out parameters:"
175 { $subsection "c-arrays" }
176 { $subsection "c-out-params" } ;
177
178 ARTICLE: "c-arrays" "C arrays"
179 "When calling a C function expecting an array as input, use a utility word which allocates a byte array of the correct size:"
180 { $subsection <c-array> }
181 "To learn how to allocate an unmanaged block from the operating system suitable for holding a C array, see " { $link "malloc" } "."
182 $terpri
183 "Each C type has a pair of words, " { $snippet { $emphasis "type" } "-nth" } " and " 
184 "Each C type has a pair of words, " { $snippet "set-" { $emphasis "type" } "-nth" } ", for reading and writing values of this type stored in an array. This set of words includes but is not limited to:"
185 { $subsection char-nth }
186 { $subsection set-char-nth }
187 { $subsection uchar-nth }
188 { $subsection set-uchar-nth }
189 { $subsection short-nth }
190 { $subsection set-short-nth }
191 { $subsection ushort-nth }
192 { $subsection set-ushort-nth }
193 { $subsection int-nth }
194 { $subsection set-int-nth }
195 { $subsection uint-nth }
196 { $subsection set-uint-nth }
197 { $subsection long-nth }
198 { $subsection set-long-nth }
199 { $subsection ulong-nth }
200 { $subsection set-ulong-nth }
201 { $subsection longlong-nth }
202 { $subsection set-longlong-nth }
203 { $subsection ulonglong-nth }
204 { $subsection set-ulonglong-nth }
205 { $subsection float-nth }
206 { $subsection set-float-nth }
207 { $subsection double-nth }
208 { $subsection set-double-nth }
209 { $subsection void*-nth }
210 { $subsection set-void*-nth }
211 { $subsection char*-nth }
212 { $subsection ushort*-nth }
213 "Byte arrays can also be created with an arbitrary size:"
214 { $subsection <byte-array> }
215 ;
216
217 ARTICLE: "c-out-params" "Output parameters in C"
218 "A frequently-occurring idiom in C code is the \"out parameter\". If a C function returns more than one value, the caller passes pointers of the correct type, and the C function writes its return values to those locations."
219 $terpri
220 "Each numerical C type, together with " { $snippet "void*" } ", has an associated " { $emphasis "out parameter constructor" } " word which takes a Factor object as input, constructs a byte array of the correct size, and converts the Factor object to a C value stored into the byte array:"
221 { $subsection <char> }
222 { $subsection <uchar> }
223 { $subsection <short> }
224 { $subsection <ushort> }
225 { $subsection <int> }
226 { $subsection <uint> }
227 { $subsection <long> }
228 { $subsection <ulong> }
229 { $subsection <longlong> }
230 { $subsection <ulonglong> }
231 { $subsection <float> }
232 { $subsection <double> }
233 { $subsection <void*> }
234 "You call the out parameter constructor with the required initial value, then pass the byte array to the C function, which receives a pointer to the start of the byte array's data area. The C function then returns, leaving the result in the byte array; you read it back using the next set of words:"
235 { $subsection *char }
236 { $subsection *uchar }
237 { $subsection *short }
238 { $subsection *ushort }
239 { $subsection *int }
240 { $subsection *uint }
241 { $subsection *long }
242 { $subsection *ulong }
243 { $subsection *longlong }
244 { $subsection *ulonglong }
245 { $subsection *float }
246 { $subsection *double }
247 { $subsection *void* }
248 { $subsection *char* }
249 { $subsection *ushort* }
250 "Note that while structure and union types do not get these words defined for them, there is no loss of generality since " { $link <void*> } " and " { $link *void* } " may be used." ;
251
252 ARTICLE: "malloc" "Manual memory management"
253 "Sometimes data passed to C functions must be allocated at a fixed address so that C code can safely store pointers."
254 $terpri
255 "The following words mirror " { $link <c-object> } ", " { $link <c-array> } " and " { $link string>char-alien } ":"
256 { $subsection <malloc-object> }
257 { $subsection <malloc-array> }
258 { $subsection <malloc-string> }
259 "These words are built on some words in the " { $vocab-link "libc" } " vocabulary, which themselves use the C library interface to call C standard library functions:"
260 { $subsection malloc }
261 { $subsection calloc }
262 { $subsection realloc }
263 { $subsection check-ptr }
264 "You must always free pointers returned by any of the above words:"
265 { $subsection free } ;
266
267 ARTICLE: "dll-internals" "DLL handles"
268 "DLL handles are a built-in class of objects which represent loaded native libraries. DLL handles are instances of the " { $link dll } " class, and have a literal syntax used for debugging prinouts; see " { $link "syntax-aliens" } "."
269 $terpri
270 "Usually one never has to deal with DLL handles directly; the C library interface creates them as required. However if direct access to these operating system facilities is required, the following primitives can be used:"
271 { $subsection dlopen }
272 { $subsection dlsym }
273 { $subsection dlclose } ;