source: project/wiki/eggref/5/bind @ 36727

Last change on this file since 36727 was 35595, checked in by felix winkelmann, 15 months ago

wiki pages for silex/bind for C5

File size: 27.4 KB
Line 
1[[tags: egg ffi]]
2[[toc:]]
3
4== bind
5
6Generates wrappers from C/C++ source code.
7
8=== Usage
9
10  (require-extension bind)
11
12=== Requirements
13
14* [[silex]]
15* [[matchable]]
16* [[coops]]
17
18=== Documentation
19
20This extension provides a parser for a restricted subset of C and C++
21that allows the easy generation of foreign variable declarations,
22procedure bindings and C++ class wrappers. The parser is invoked via
23the {{bind}} form, which extracts binding information and generates
24the necessary code. An example:
25
26<enscript highlight=scheme>
27(bind "double sin(double);")
28
29(print (sin 3.14))
30</enscript>
31
32The parser would generate code that is equivalent to
33
34  (define sin (foreign-lambda double "sin" double))
35
36Another example, here using C++. Consider the following class:
37
38 // file: foo.h
39 
40 class Foo {
41  private:
42   int x_;
43  public:
44   Foo(int x);
45   void setX(int x);
46   int getX();
47 };
48
49To generate a wrapper class that provides generic functions for the
50constructor and the {{setX}} and {{getX}} methods, we
51can use the following class definition:
52
53 ; file: test-foo.scm
54
55 (require-extension bind coops cplusplus-object)
56 
57 (bind* "#include \"Foo.h\"")
58 
59 (define x (new <Foo> 99))
60 (print (getX x))              ; prints ''99''
61 (setX x 42)
62 (print (getX x))              ; prints ''42''
63 (delete x)
64
65Provided the file {{foo.o}} contains the implementation of the class {{Foo}}, the
66given example could be compiled like this (assuming a UNIX like environment):
67
68 % csc test-foo.scm foo.o -c++
69
70To use the C++ interface, the [[coops]] extension is needed.
71Additionally, the class {{<c++-object>}} must be available, which is
72provided in the {{cplusplus-object}} extension.
73
74To use this facility, you can either use the syntactic forms provided
75by the {{bind}} extension or run the {{chicken-bind}} standalone program
76to process a C/C++ file and generate a file containing wrapper code which
77then can be compiled with the CHICKEN compiler.
78
79As a debugging aid, you can pass {{-debug F}} to the Scheme compiler to see
80the generated wrapper code.
81
82{{chicken-bind}} accepts a number of command-line options to enable/disable
83various options, enter
84
85  % chicken-bind -help
86
87for more information.
88
89=== General operation
90
91The parser will generally perform the following functions:
92
93* Translate macro, enum-definitions and constants into {{define-foreign-variable}} or {{define-constant}} forms
94
95* Translate function prototypes into {{foreign-lambda}} forms
96
97* Translate variable declarations into accessor procedures
98
99* Handle (very) basic preprocessor operations
100
101* Translate simple C++ class definitions into {{coops}} wrapper classes and methods
102
103Basic token-substitution of macros defined via {{#define}} is
104performed. The preprocessor commands {{#ifdef}}, {{#ifndef}},
105{{#else}}, {{#endif}}, {{#undef}} and {{#error}} are handled. The
106preprocessor commands {{#if}} and {{#elif}} are not supported and will
107signal an error when encountered by the parser, because C expressions
108(even if constant) are not parsed.  The preprocessor command
109{{#pragma}} is allowed but will be ignored.
110
111During processing of C code, the macro {{CHICKEN}} is defined (similar
112to the C compiler option {{-DCHICKEN}}).
113
114Macro- and type-definitions are available in subsequent
115{{bind}} declarations.  C variables declared generate a
116procedure with zero or one argument with the same name as the
117variable. When called with no arguments, the procedure returns the
118current value of the variable. When called with an argument, then the
119variable is set to the value of that argument.  C and C++ style
120comments are supported. Variables declared as {{const}} will generate
121normal Scheme variables, bound to the initial value of the variable.
122
123Function-, member-function and constructor/destructor definitions may
124be preceded by the {{___safe}} qualifier, which marks the function as
125(possibly) performing a callback into Scheme. If a wrapped function
126calls back into Scheme code, and {{___safe}} has not been given very
127strange and hard to debug problems will occur.
128
129Functions and member functions prefixed with {{___discard}} and a
130result type that maps to a Scheme string ({{c-string}}), will have
131their result type changed to {{c-string*}} instead.
132
133Constants (as declared by {{#define}} or {{enum}}) are not visible
134outside of the current Compilation units unless the
135{{export-constants}} option has been enabled.  Only numeric
136or character constants are directly supported.
137
138Function-arguments may be preceded by {{___in}}, {{___out}} and
139{{___inout}} qualifiers to specify values that are passed by reference
140to a function, or returned by reference. Only basic types (booleans,
141numbers and characters) can be passed using this method.  During the
142call a pointer to a temporary piece of storage containing the initial
143value (or a random value, for {{___out}} parameters) will be allocated
144and passed to the wrapped function. This piece of storage is subject
145to garbage collection and will move, should a callback into Scheme
146occur that triggers a garbage collection. Multiple {{__out}} and
147{{___inout}} parameters will be returned as multiple values, preceded
148by the normal return value of thhe function (if not {{void}}). Here is
149a simple example:
150
151 (bind* #<<EOF
152 #ifndef CHICKEN
153 #include <math.h>
154 #endif
155
156 double modf(double x, ___out double *iptr);
157 EOF
158 )
159
160 (let-values ([(frac int) (modf 33.44)])
161   ...)
162
163Function-arguments may be preceded by {{___length(ID)}}, where {{ID}}
164designates the name of another argument that must refer to a number
165vector or string argument. The value of the former argument will be
166computed at run-time and thus can be omitted:
167
168 (require-extension srfi-4)
169
170 (bind* #<<EOF
171 double sumarray(double *arr, ___length(arr) int len)
172 {
173   double sum = 0;
174
175   while(len--) sum += *(arr++);
176
177   return sum;
178 }
179 EOF
180 )
181
182 (print (sumarray (f64vector 33 44 55.66)))
183
184The length variable may be positioned anywhere in the argument
185list. Length markers may only be specified for arguments passed as
186SRFI-4 byte-vectors, byte-vectors (as provided by the {{lolevel}}
187library unit) or strings.
188
189Structure and union definitions containing actual field declarations
190generate getter procedures (and SRFI-17 setters when declared
191{{___mutable}} or the {{mutable-fields}} option has been
192enabled) The names of these procedures are computed by concatenating the
193struct (or union) name, a hyphen ({{"-"}}) and the field
194name. Structure definitions with fields may not be used in positions
195where a type specifier is normally expected. The field accessors
196operate on struct/union pointers only.  Additionally a zero-argument
197procedure named {{make-<structname>}} will be generated that allocates
198enough storage to hold an instance of the structure (or union).
199Prefixing the definition with {{___abstract}} will omit the creation
200procedure.
201
202 (bind* #<<EOF
203 struct My_struct { int x; ___mutable float y; };
204
205 typedef struct My_struct My_struct;
206
207 My_struct *make_struct(int x, float y)
208 {
209   My_struct *s = (My_struct *)malloc(sizeof(My_struct));
210   s->x = x;
211   s->y = y;
212   return s;
213 }
214 EOF
215 )
216
217will generate the following definitions:
218
219 (make-My_struct) -> PTR
220 (My_struct-x PTR) -> INT
221 (My_struct-y PTR) -> FLOAT
222 (set! (My_struct-y PTR) FLOAT)
223 (make_struct INT FLOAT) -> PTR
224
225As of version 1.0, nested structs are supported. While nested unions
226are not, pointers to either unions and structs are.
227
228Mutable struct-members of type {{c-string}} or {{c-string*}} will copy
229the passed argument string when assigned (using {{strdup(3)}}), since
230data may move in subsequent garbage collections.
231
232All specially handled tokens preceded with {{___}} are defined as C
233macros in the headerfile {{chicken.h}} and will usually expand into
234nothing, so they don't invalidate the processed source code.
235
236C++ {{namespace}} declarations of the form {{namespace NAME @{... @}}}
237recognized but will be completely ignored.
238
239Keep in mind that this is not a fully general C/C++ parser. Taking an
240arbitrary headerfile and feeding it to {{bind}} will in most cases not
241work or generate riduculuous amounts of code. This FFI facility is for
242carefully written headerfiles, and for declarations directly embedded
243into Scheme code.
244
245=== Syntactic forms
246
247==== bind
248
249<macro>(bind STRING ...)</macro>
250
251Parses the C code in {{STRING ...}} and expands into wrapper
252code providing access to the declarations defined in it.
253
254==== bind*
255
256<macro>(bind* STRING ...)</macro>
257
258Similar to {{bind}}, but also embeds the code in the generated
259Scheme expansion using {{foreign-declare}}.
260
261==== bind-type
262
263<macro>(bind-type TYPENAME SCHEMETYPE [CONVERTARGUMENT [CONVERTRESULT]])</macro>
264
265Declares a foreign type transformation, similar to
266{{define-foreign-type}}. There should be two to four arguments: a C
267typename, a Scheme foreign type specifier and optional argument- and
268result-value conversion procedures.
269
270 ;;;; foreign type that converts to unicode (assumes 4-byte wchar_t):
271 ;
272 ; - Note: this is rather kludgy and is only meant to demonstrate the `bind-type'
273 ;         syntax
274
275 (require-extension srfi-4 bind)
276
277 (define mbstowcs (foreign-lambda int "mbstowcs" nonnull-u32vector c-string int))
278
279 (define (str->ustr str)
280   (let* ([len (string-length str)]
281          [us (make-u32vector (add1 len) 0)] )
282     (mbstowcs us str len)
283     us) )
284
285 (bind-type unicode nonnull-u32vector str->ustr)
286
287 (bind* #<<EOF
288 static void foo(unicode ws)
289 {
290   printf("%ls\n", ws);
291 }
292 EOF
293 )
294
295 (foo "this is a test!")
296
297==== bind-opaque-type
298
299<macro>(bind-opaque-type TYPENAME SCHEMETYPE)</macro>
300
301Similar to {{bind-type}}, but provides automatic argument- and result
302conversions to wrap a value into a structure:
303
304 (bind-opaque-type myfile (pointer "FILE"))
305
306 (bind "myfile fopen(char *, char *);")
307
308 (fopen "somefile" "r")   ==> <myfile>
309
310{{(bind-opaque-type TYPENAME TYPE)}} is basically equivalent to
311{{(bind-type TYPENAME TYPE TYPE->RECORD RECORD->TYPE)}} where
312{{TYPE->RECORD}} and {{RECORD->TYPE}} are compiler-generated conversion
313functions that wrap objects of type {{TYPE}} into a record and back.
314
315==== bind-file
316
317<macro>(bind-file FILENAME ...)</macro>
318
319Reads the content of the given files and generates wrappers using {{bind}}.
320Note that {{FILENAME ...}} is not evaluated.
321
322==== bind-file*
323
324<macro>(bind-file* FILENAME ...)</macro>
325
326Reads the content of the given files and generates wrappers using {{bind*}}.
327 
328==== bind-rename
329
330<macro>(bind-rename CNAME SCHEMENAME)</macro>
331
332Defines to what a certain C/C++ name should be renamed. {{CNAME}}
333specifies the C/C++ identifier occurring in the parsed text and
334{{SCHEMENAME}} gives the name used in generated wrapper code.
335
336==== bind-rename/pattern
337
338<macro>(bind-rename/pattern REGEX REPLACEMENT)</macro>
339
340Declares a renaming pattern to be used for C/C++ identifiers occuring
341in bound code. {{REGEX}} should be a string or SRE and replacement a
342string, which may optionally contain back-references to matched
343sub-patterns.
344
345==== bind-options
346
347<macro>(bind-options OPTION VALUE ...)</macro>
348
349Enables various translation options, where {{OPTION}} is a keyword
350and VALUE is a value given to that option. Note that {{VALUE}} is
351not evaluated.
352
353Possible options are:
354
355===== export-constants
356
357 export-constants: BOOLEAN
358
359Define global variables for constant-declarations (with {{#define}} or
360{{enum}}), making the constant available outside the current
361compilation unit.
362
363===== class-finalizers
364
365 class-finalizers: BOOLEAN
366
367Automatically generates calls to {{set-finalizer!}} so that any unused
368references to instances of subsequently defined C++ class wrappers
369will be destroyed. This should be used with care: if the embedded C++
370object which is represented by the reclaimed {{coops}} instance is
371still in use in foreign code, unpredictable things will happen.
372
373===== mutable-fields
374
375 mutable-fields: BOOLEAN
376
377Specifies that all struct or union fields should generate setter
378procedures (the default is to generate only setter procedures for
379fields declared {{___mutable}}).
380
381===== constructor-name
382
383 constructor-name: STRING
384
385Specifies an alternative name for constructor methods (the default is {{constructor}}),
386a default-method for which is defined in the {{cplusplus-object}} extension.
387
388===== destructor-name
389
390 destructor-name: STRING
391
392Specifies an alternative name for destructor methods (the default is {{destructor}}),
393a default-method for which is defined in the {{cplusplus-object}} extension.
394
395===== exception-handler
396
397 exception-handler: STRING
398
399Defines C++ code to be executed when an exception is triggered inside
400a C++ class member function. The code should be one or more {{catch}}
401forms that perform any actions that should be taken in case an
402exception is thrown by the wrapped member function:
403
404 (bind-options exception-handler: "catch(...) { return 0; }")
405
406 (bind* #<<EOF
407 class Foo {
408  public:
409   Foo *bar(bool f) { if(f) throw 123; else return this; }
410 };
411 EOF
412 )
413
414 (define f1 (new <Foo>))
415 (print (bar f1 #f))
416 (print (bar f1 #t))
417 (delete f1)
418
419will print {{<Foo>}} and {{#f}}, respectively.
420
421===== full-specialization
422
423 full-specialization: BOOLEAN
424
425Enables ''full specialization'' mode. In this mode all wrappers for
426functions, member functions and static member functions are created as
427fully specialized {{coops}} methods. This can be used to handle
428overloaded C++ functions properly. Only a certain set of foreign
429argument types can be mapped to {{coops}} classes, as listed in the
430following table:
431
432<table>
433<tr><th>Type</th><th>Class</th></tr>
434<tr><td>char</td><td>{{&lt;char>}}</td></tr>
435<tr><td>bool</td><td>{{&lt;bool>}}</td></tr>
436<tr><td>c-string</td><td>{{&lt;string>}}</td></tr>
437<tr><td>unsigned-char</td><td>{{&lt;exact>}}</td></tr>
438<tr><td>byte</td><td>{{&lt;exact>}}</td></tr>
439<tr><td>unsigned-byte</td><td>{{&lt;exact>}}</td></tr>
440<tr><td>[unsigned-]int</td><td>{{&lt;exact>}}</td></tr>
441<tr><td>[unsigned-]short</td><td>{{&lt;exact>}}</td></tr>
442<tr><td>[unsigned-]long</td><td>{{&lt;integer>}}</td></tr>
443<tr><td>[unsigned-]integer</td><td>{{&lt;integer>}}</td></tr>
444<tr><td>float</td><td>{{&lt;inexact>}}</td></tr>
445<tr><td>double</td><td>{{&lt;inexact>}}</td></tr>
446<tr><td>number</td><td>{{&lt;number>}}</td></tr>
447<tr><td>(enum _)char</td><td>{{&lt;exact>}}</td></tr>
448<tr><td>(const T)char</td><td>(as T)</td></tr>
449<tr><td>(function ...)</td><td>{{&lt;pointer>}}</td></tr>
450<tr><td>c-pointer</td><td>{{&lt;pointer>}}</td></tr>
451<tr><td>(pointer _)</td><td>{{&lt;pointer>}}</td></tr>
452<tr><td>(c-pointer _)</td><td>{{&lt;pointer>}}</td></tr>
453<tr><td>u8vector</td><td>{{&lt;u8vector>}}</td></tr>
454<tr><td>s8vector</td><td>{{&lt;s8vector>}}</td></tr>
455<tr><td>u16vector</td><td>{{&lt;u16vector>}}</td></tr>
456<tr><td>s16vector</td><td>{{&lt;s16vector>}}</td></tr>
457<tr><td>u32vector</td><td>{{&lt;u32vector>}}</td></tr>
458<tr><td>s32vector</td><td>{{&lt;s32vector>}}</td></tr>
459<tr><td>f32vector</td><td>{{&lt;f32vector>}}</td></tr>
460<tr><td>f64vector</td><td>{{&lt;f64vector>}}</td></tr>
461</table>
462
463All other foreign types are specialized as {{#t}}.
464
465Full specialization can be enabled globally, or only for sections of code by
466enclosing it in
467
468 (bind-options full-specialization: #t)
469
470 (bind #<<EOF
471 ...
472 int foo(int x);
473 int foo(char *x);
474 ...
475 EOF
476 )
477
478 (bind-options full-specialization: #f)
479
480Alternatively, member function definitions may be prefixed by {{___specialize}} for specializing
481only specific members.
482
483===== prefix
484
485  prefix: STRING
486
487Sets a prefix that should be be added to all generated Scheme identifiers. For example
488
489 (bind-options prefix: "mylib:")
490
491 (bind "#define SOME_CONST 42")
492
493would generate the following code:
494
495 (define-constant mylib:SOME_CONST 42)
496
497To switch prefixing off, use the value {{#f}}. Prefixes are not applied to
498Class names.
499
500===== default-renaming
501
502 default_renaming: STRING
503
504Chooses a standard name-transformation, converting underscores ({{_}})
505to hyphens ({{-}}) and transforming ''CamelCase'' into
506''camel-case''. All uppercase characters are also converted to
507lowercase. The result is prefixed with the argument {{STRING}} (equivalent
508to the {{prefix}} ption).
509
510===== foreign-transform
511
512 foreign-transformer: procedure
513
514Applies the supplied procedure before emitting code. Note that the procedure is evaluated at compile-time. You can reference procedure-names when you use define-for-syntax. The procedure takes in two arguments: a bind-foreign-lambda sexpression and a rename procedure (for hygienic macros). The car of bind-foreign-lambda form is either a renamed version of 'foreign-lambda*' or 'foreign-safe-lambda*'.
515
516  (define-for-syntax (my-transformer form rename)
517    (pp form) `(lambda () #f)) ;; prints and disables all bindings!
518  (bind-options foreign-transformer: my-transformer)
519  (bind "void foo();")
520
521foreign-transformer may be useful with large header-files that require custom type-conversion, where bind-foreign-type isn't flexible enough. It is possible to write foreig-transformers that allow returning structs by value, for example, by converting to a blob or u8vector.
522
523bind-foreign-lambdas are similar to foreign-lambdas, but use s-expressions instead of flat C strings to allow simple modification. See some of the tests for how these may be used: [[http://bugs.call-cc.org/browser/release/4/bind/trunk/tests]].
524
525==== bind-include-path
526
527<macro>(bind-include-path STRING ...)</macro>
528
529Appends the paths given in {{STRING ...}} to the list of available include
530paths to be searched when an {{#include ...}} form is processed by {{bind}}.
531
532=== Grammar
533
534The parser understand the following grammar:
535
536 PROGRAM = PPCOMMAND
537         | DECLARATION ";"
538 
539 PPCOMMAND = "#define" ID [TOKEN ...]
540           | "#ifdef" ID
541           | "#ifndef" ID
542           | "#else"
543           | "#endif"
544           | "#undef" ID
545           | "#error" TOKEN ...
546           | "#include" INCLUDEFILE
547           | "#import" INCLUDEFILE
548           | "#pragma" TOKEN ...
549 
550 DECLARATION = FUNCTION
551             | VARIABLE
552             | ENUM
553             | TYPEDEF
554             | CLASS
555             | CONSTANT
556             | STRUCT
557             | NAMESPACE
558             | USING
559 
560 STRUCT = ("struct" | "union") ID ["{" {["___mutable"] TYPE {"*"} ID {"," {"*"} ID}} "}]
561 
562 NAMESPACE = "namespace" ID "{" DECLARATION ... "}"
563 
564 USING = "using" "namespace" ID
565 
566 INCLUDEFILE = "\"" ... "\""
567             | "<" ... ">"
568 
569 FUNCTION = {"___safe" | "___specialize" | "___discard"} [STORAGE] TYPE ID "(" ARGTYPE "," ... ")" [CODE]
570          | {"___safe" | "___specialize" | "___discard"} [STORAGE] TYPE ID "(" "void" ")" [CODE]
571 
572 ARGTYPE = [IOQUALIFIER] TYPE [ID ["=" NUMBER]]
573 
574 IOQUALIFIER = "___in" | "___out" | "___inout" | LENQUALIFIER
575 
576 LENQUALIFIER = "___length" "(" ID ")"
577 
578 VARIABLE = [STORAGE] ENTITY ["=" INITDATA]
579 
580 ENTITY = TYPE ID ["[" ... "]"]
581 
582 STORAGE = "extern" | "static" | "volatile" | "inline"
583 
584 CONSTANT = "const" TYPE ID "=" INITDATA
585 
586 ENUM = "enum" "{" ID ["=" (NUMBER | ID)] "," ... "}"
587 
588 TYPEDEF = "typedef" TYPE ["*" ...] [ID]
589 
590 TYPE = ["const"] BASICTYPE [("*" ... | "&" | "<" TYPE "," ... ">" | "(" "*" [ID] ")" "(" TYPE "," ... ")")]
591 
592 BASICTYPE = ["unsigned" | "signed"] "int"
593           | ["unsigned" | "signed"] "char"
594           | ["unsigned" | "signed"] "short" ["int"]
595           | ["unsigned" | "signed"] "long" ["int"]
596           | ["unsigned" | "signed"] "___byte"
597           | "size_t"
598           | "float"
599           | "double"
600           | "void"
601           | "bool"
602           | "___bool"
603           | "___scheme_value"
604           | "___scheme_pointer"
605           | "___byte_vector"
606           | "___pointer_vector"
607           | "___pointer" TYPE "*"
608           | "C_word"
609           | "___fixnum"
610           | "___number"
611           | "___symbol"
612           | "___u32"
613           | "___s32"
614           | "___s64"
615           | "__int64"
616           | "int64_t"
617           | "uint32_t"
618           | "uint64_t"
619           | "struct" ID
620           | "union" ID
621           | "enum" ID
622           | ID
623 
624 CLASS = ["___abstract"] "class" ID [":" [QUALIFIER] ID "," ...] "{" MEMBER ... "}"
625 
626 MEMBER = [QUALIFIER ":"] ["virtual"] (MEMBERVARIABLE | CONSTRUCTOR | DESTRUCTOR | MEMBERFUNCTION)
627 
628 MEMBERVARIABLE = TYPE ID ["=" INITDATA]
629 
630 MEMBERFUNCTION = {"___safe" | "static" | "___specialize" | "___discard"} TYPE ID "(" ARGTYPE "," ... ")" ["const"] ["=" "0"] [CODE]
631                | {"___safe" | "static" | "___specialize" | "___discard"} TYPE ID "(" "void" ")" ["const"] ["=" "0"] [CODE]
632 
633 CONSTRUCTOR = ["___safe"] ["explicit"] ID "(" ARGTYPE "," ... ")" [BASECONSTRUCTORS] [CODE]
634 
635 DESTRUCTOR = ["___safe"] "~" ID "(" ["void"] ")" [CODE]
636 
637 QUALIFIER = ("public" | "private" | "protected")
638 
639 NUMBER = <a C integer or floating-point number, in decimal, octal or hexadecimal notation>
640 
641 INITDATA = <everything up to end of chunk>
642 
643 BASECONSTRUCTORS = <everything up to end of chunk>
644 
645 CODE = <everything up to end of chunk>
646
647The following table shows how argument-types are translated:
648
649<table>
650<tr><th>C type</th><th>Scheme type</th></tr>
651<tr><td>[unsigned] char</td><td>char</td></tr>
652<tr><td>[unsigned] short</td><td>[unsigned-]short</td></tr>
653<tr><td>[unsigned] int</td><td>[unsigned-]integer</td></tr>
654<tr><td>[unsigned] long</td><td>[unsigned-]long</td></tr>
655<tr><td>___u32</td><td>unsigned-integer32
656</td></tr><tr><td>___s32</td><td>integer32
657</td></tr><tr><td>___s64</td><td>integer64
658</td></tr><tr><td>int64_t</td><td>integer64
659</td></tr><tr><td>__int64</td><td>integer64
660</td></tr><tr><td>uint32_t</td><td>unsigned-integer32
661</td></tr><tr><td>uint64_t</td><td>unsigned-integer64
662</td></tr><tr><td>float</td><td>float
663</td></tr><tr><td>double</td><td>double
664</td></tr><tr><td>size_t</td><td>unsigned-integer
665</td></tr><tr><td>bool</td><td>int
666</td></tr><tr><td>___bool</td><td>int
667</td></tr><tr><td>___fixnum</td><td>int
668</td></tr><tr><td>___number</td><td>number
669</td></tr><tr><td>___symbol</td><td>symbol
670</td></tr><tr><td>___scheme_value</td><td>scheme-object
671</td></tr><tr><td>C_word</td><td>scheme-object
672</td></tr><tr><td>___scheme_pointer</td><td>scheme-pointer
673</td></tr>
674<tr><td> char *</td><td>c-string</td></tr>
675<tr><td>signed char *</td><td>s8vector</td></tr>
676<tr><td>[signed] short *</td><td>s16vector</td></tr>
677<tr><td> [signed] int *</td><td>s32vector</td></tr>
678<tr><td> [signed] long *</td><td>s32vector</td></tr>
679<tr><td> unsigned char *</td><td>u8vector</td></tr>
680<tr><td> unsigned short *</td><td>u16vector</td></tr>
681<tr><td> unsigned int *</td><td>u32vector</td></tr>
682<tr><td> unsigned long *</td><td>u32vector</td></tr>
683<tr><td> float *</td><td>f32vector</td></tr>
684<tr><td> double *</td><td>f64vector</td></tr>
685<tr><td>___byte_vector</td><td>byte-vector</td></tr>
686<tr><td>___pointer_vector</td><td>pointer-vector</td></tr>
687<tr><td> CLASS *</td><td>(instance CLASS &lt;CLASS>)</td></tr>
688<tr><td> CLASS &</td><td>(instance-ref CLASS &lt;CLASS>)</td></tr>
689<tr><td> TYPE *</td><td>(pointer TYPE)</td></tr>
690<tr><td> TYPE &</td><td>(ref TYPE)</td></tr>
691<tr><td> TYPE&lt;T1, ...></td><td>(template TYPE T1 ...)</td></tr>
692<tr><td> TYPE1 (*)(TYPE2, ...)</td><td>(function TYPE1 (TYPE2 ...))</td></tr>
693</table>
694
695The following table shows how result-types are translated:
696
697<table>
698<tr><th>C type                 </th><th>Scheme type</th></tr>
699<tr><td>void                   </td><td>void</td></tr>
700<tr><td>[unsigned] char        </td><td>char</td></tr>
701<tr><td>[unsigned] short       </td><td>[unsigned-]short</td></tr>
702<tr><td>[unsigned] int         </td><td>[unsigned-]integer</td></tr>
703<tr><td>[unsigned] long        </td><td>[unsigned-]long</td></tr>
704<tr><td>___u32                 </td><td>unsigned-integer32</td></tr>
705<tr><td>___s32                 </td><td>integer32</td></tr>
706<tr><td>___s64                 </td><td>integer64</td></tr>
707<tr><td>int64_t                </td><td>integer64</td></tr>
708<tr><td>__int64                </td><td>integer64</td></tr>
709<tr><td>uint64_t               </td><td>unsigned-integer64</td></tr>
710<tr><td>__uint64               </td><td>unsigned-integer64</td></tr>
711<tr><td>float                  </td><td>float</td></tr>
712<tr><td>double                 </td><td>double</td></tr>
713<tr><td>size_t                 </td><td>unsigned-integer</td></tr>
714<tr><td>bool                   </td><td>bool</td></tr>
715<tr><td>___bool                </td><td>bool</td></tr>
716<tr><td>___fixnum              </td><td>int</td></tr>
717<tr><td>___number              </td><td>number</td></tr>
718<tr><td>___symbol              </td><td>symbol</td></tr>
719<tr><td>___scheme_value        </td><td>scheme-object</td></tr>
720<tr><td>char *                 </td><td>c-string</td></tr>
721<tr><td>TYPE *                 </td><td>(c-pointer TYPE)</td></tr>
722<tr><td>TYPE &                 </td><td>(ref TYPE)</td></tr>
723<tr><td>TYPE&lt;T1, ...>       </td><td>(template TYPE T1 ...)</td></tr>
724<tr><td>TYPE1 (*)(TYPE2, ...)  </td><td>(function TYPE1 (TYPE2 ...))</td></tr>
725<tr><td>CLASS *                </td><td>(instance CLASS &lt;CLASS>)</td></tr>
726<tr><td>CLASS &                </td><td>(instance-ref CLASS &lt;CLASS>)</td></tr>
727</table>
728
729The {{___pointer}} argument marker disables automatic simplification
730of pointers to number-vectors and C-strings: normally arguments of
731type {{int *}} are handled as SRFI-4 {{s32vector}} number vectors. To
732force treatment as a pointer argument, precede the argument type with
733{{___pointer}}. The same applies to strings: {{char *}} is by default
734translated to the foreign type {{c-string}}, but {{___pointer char *}}
735is translated to {{(c-pointer char)}}.
736
737
738=== C notes
739
740Foreign variable definitions for macros are not exported from the
741current compilation unit, but definitions for C variables and
742functions are.
743
744{{bind}} does not embed the text into the generated C file,
745use {{bind*}} for that.
746
747Functions with variable number of arguments are not supported.
748
749=== C++ notes
750
751Each C++ class defines a {{coops}} class, which is a subclass of
752{{<c++-object>}}. Instances of this class contain a single slot named
753{{this}}, which holds a pointer to a heap-allocated C++ instance.  The
754name of the {{coops}} class is obtained by putting the C++ classname
755between angled brackets ({{<...>}}).  {{coops}} classes are not seen by
756C++ code.
757
758The C++ constructor is invoked by the {{constructor}} generic, which
759accepts as many arguments as the constructor. If no constructor is
760defined, a default-constructor will be provided taking no arguments.
761
762To release the storage allocated for a C++ instance invoke the {{delete}} generic
763(the name can be changed by using the {{destructor-name}} option).
764
765Static member functions are wrapped in a Scheme procedure named {{<class>::<member>}}.
766
767Member variables and non-public member functions are ignored.
768
769Virtual member functions are not seen by C++ code. Overriding a
770virtual member function with a {{coops}} method will not work when the
771member function is called by C++.
772
773Operator functions and default arguments are not supported.
774
775Exceptions must be explicitly handled by user code and may not be
776thrown beyond an invocation of C++ by Scheme code.
777
778Generally, the following interface to the creation and destruction
779of wrapped C++ instances is provided:
780
781==== constructor
782
783<procedure>(constructor CLASS INITARGS)</procedure>
784
785A generic function that, when invoked will construct a C++ object represented
786by the class {{CLASS}}, which should inherit from {{<c++-object>}}. {{INITARGS}}
787is a list of arguments that should be passed to the constructor and which must
788match the argument types for the wrapped constructor.
789
790==== destructor
791
792<procedure>(destructor OBJECT)</procedure>
793
794A generic function that, when invoked will destroy the wrapped C++ object {{OBJECT}}.
795
796===== new
797
798<procedure>(new CLASS ARG1 ...)</procedure>
799
800A convenience procedure that invokes the {{constructor}} generic function for {{CLASS}}.
801
802===== delete
803
804<procedure>(delete OBJECT)</procedure>
805
806A convenience procedure that invokes the {{destructor}} generic method of {{OBJECT}}.
807
808== Authors
809
810[[/users/felix winkelmann|felix winkelmann]] and Kristian Lein-Mathisen
811
812== License
813
814This code is placed into the public domain.
815
816== Version History
817
818; 1.0 : initial release for CHICKEN 4, based on version 1.2 from CHICKEN 4
Note: See TracBrowser for help on using the repository browser.