source: project/wiki/eggref/4/easyffi @ 20561

Last change on this file since 20561 was 20561, checked in by felix winkelmann, 10 years ago

easyffi and regex page fixes

File size: 29.0 KB
Line 
1[[tags: egg ffi]]
2[[toc:]]
3
4== The "Easy" Foreign Function Interface
5
6''Note: see [[/eggref/4/bind|bind]] for a newer version of this
7extension that provides a simplified interface and better [[/eggref/4/coops|coops]]
8integration.''
9
10This extension provides a parser for a restricted subset of C and C++ that
11allows the easy generation of foreign variable declarations, procedure bindings and
12C++ class wrappers. The parser is invoked via the
13{{foreign-parse}} form, which extracts binding information and generates
14the necessary code. An example:
15
16<enscript highlight=scheme>
17(foreign-declare "
18#include <math.h>
19")
20
21(foreign-parse "extern double sin(double);")
22
23(print (sin 3.14))
24</enscript>
25
26The parser would generate code that is equivalent to
27
28 (foreign-declare "
29 #include <math.h>
30 ")
31
32 (define sin (foreign-lambda double "sin" double))
33
34Note that the read syntax {{#>[SPEC] ... <#}}
35provides a somewhat simpler way of using the parser. The example above could
36alternatively be expressed as
37
38 #>!
39 extern double sin(double);
40 <#
41
42 (print (sin 3.14))
43
44Another example, here using C++. Consider the following class:
45
46 // file: foo.h
47 
48 class Foo {
49  private:
50   int x_;
51  public:
52   Foo(int x);
53   void setX(int x);
54   int getX();
55 };
56
57To generate a wrapper class that provides generic functions for the
58constructor and the {{setX}} and {{getX}} methods, we
59can use the following class definition:
60
61 ; file: test-foo.scm
62
63 (require-extension tinyclos)
64 
65 #>!
66 #include "Foo.h"
67 <#
68 
69 (define x (make <Foo> 99))
70 (print (getX x))              ; prints ''99''
71 (setX x 42)
72 (print (getX x))              ; prints ''42''
73 (destroy x)
74
75Provided the file {{foo.o}} contains the implementation of the class {{Foo}}, the
76given example could be compiled like this (assuming a UNIX like environment):
77
78 % csc -X easyffi test-foo.scm foo.o -c++
79
80To use the C++ interface, the [[tinyclos]] extension is needed.
81
82Here is another example, a minimal ''Hello world'' application for QT. We can
83see the three different ways of embedding C/C++ code in Scheme:
84
85 ; compile like this:
86 ; csc -X easyffi hello.scm -c++ -C -IQTDIR/include -L "-LQTDIR/lib -lqt"
87 
88 (require-extension tinyclos)
89
90 ; Include into generated code, but don't parse:
91 #>
92 #include <qapplication.h>
93 #include <qpushbutton.h>
94 <#
95
96 ; Parse but don't embed: we only want wrappers for a few classes:
97 #>?
98 class QWidget
99 {
100 public:
101   void resize(int, int);
102   void show();
103 };
104
105 class QApplication
106 {
107 public:
108   QApplication(int, char **);
109   ~QApplication();
110   void setMainWidget(QWidget *);
111   void exec();
112 };
113
114 class QPushButton : public QWidget
115 {
116 public:
117   QPushButton(char *, QWidget *);
118   ~QPushButton();
119 }
120 <#
121
122 (define a (apply make <QApplication> (receive (argc+argv))))
123 (define hello (make <QPushButton> "hello world!" #f))
124 (resize hello 100 30)
125 (setMainWidget a hello)
126 (show hello)
127 (exec a)
128 (destroy hello)
129 (destroy a)
130
131
132=== Usage
133
134To use this facility, you can either run it in the interpreter and generate files with wrapper code and interact
135using an API, or you can load it as a compiler extension. To do the latter, pass {{-X easyffi}} to {{csc}} (or {{-extend easyffi}} to
136{{chicken}}). {{-R easyffi}} works also, but will not make the special read-syntax available.
137
138This extension defines the {{easyffi}} module.
139
140To see the expanded code generated during compilation, compile with {{-debug F}}.
141
142A command-line tool named {{chicken-wrap}} is also available that translates
143C source or header files into Scheme code. Enter
144
145  % chicken-wrap -help
146
147for more information.
148
149The API provides the following procedures:
150
151==== parse-easy-ffi
152
153<procedure>(parse-easy-ffi STRING)</procedure>
154
155Parses the C/C++ code in STRING and returns a list of top-level expressions representing compilable bindings to the defintions
156contained.
157
158==== register-ffi-macro
159
160<procedure>(register-ffi-macro STRING)</procedure>
161
162Defines a preprocessor macro named STRING for allowing conditional processing using {{#ifdef ... #endif}}.
163
164
165==== check-c-syntax
166
167<procedure>(check-c-syntax STRING)</procedure>
168
169Perform a superficial C/C++ syntax check and signal an error if any lexical or syntactic errors are detected.
170
171
172==== foreign-parse
173
174<macro>(foreign-parse STRING ...)</macro>
175
176Parse given strings and generate foreign-interface bindings.
177
178
179==== foreign-parse/declare
180
181<macro>(foreign-parse/declare STRING ...)</macro>
182 
183Parse and include strings into the generated code.
184
185
186==== foreign-include-path
187
188<macro>(foreign-include-path STRING ...)</macro>
189
190Appends the paths given in {{STRING ...}} to the list of available include
191paths to be searched when an {{#include ...}} form is processed by {{foreign-parse}}.
192
193
194=== #> ... <# Syntax
195
196Occurrences of the special read syntax {{#>[SPEC ...] ...<#}} will be handled according to
197{{SPEC}}:
198
199* If {{SPEC}} is the {{?}} character, the text following up to the next {{<#}} will be processed as a {{(declare (foreign-parse "..."))}} declaration (the code will be processed by the FFI parser described in this section).
200
201* If {{SPEC}} is the {{!}} character, the text will be embedded as {{(foreign-parse/declare "...")}}. It will be both included verbatim in the declaration section of the generated C/C++ file and processed by the FFI parser.
202
203* If {{SPEC}} is the {{:}} character, the text will be so it will be executed at the location where it appears.
204
205* If {{SPEC}} is a list of the form {{(TAG ...)}}, then each {{TAG}} (which should be a symbol) specifies what should be done with the text:
206
207  declare   (foreign-declare "...")
208  parse     (foreign-parse "...")
209  execute   (foreign-code "...")
210
211* If any other character follows the {{#>}}, then the complete text will be included verbatim in the declaration part of the generated file (as in a {{foreign-declare}} form).
212
213
214=== General operation
215
216The parser will generally perform the following functions
217
218* Translate macro, enum-definitions and constants into {{define-foreign-variable}} or {{define-constant}} forms
219
220* Translate function prototypes into {{foreign-lambda}} forms
221
222* Translate variable declarations into accessor procedures
223
224* Handle basic preprocessor operations
225
226* Translate simple C++ class definitions into TinyCLOS wrapper classes and methods
227
228Basic token-substitution of macros defined via {{#define}} is performed. The
229preprocessor commands {{#ifdef}}, {{#ifndef}}, {{#else}}, {{#endif}}, {{#undef}} and {{#error}}
230are handled. The preprocessor commands {{#if}} and {{#elif}} are not supported and will signal
231an error when encountered by the parser, because C expressions (even if constant) are not parsed.
232The preprocessor command {{#pragma}} is allowed but will be ignored.
233
234During processing of {{foreign-parse}} declarations the macro {{CHICKEN}} is defined (similar
235to the C compiler option {{-DCHICKEN}}).
236
237Macro- and type-definitions are available in subsequent {{foreign-parse}} declarations.
238C variables declared generate a procedure with zero or one argument with the same name
239as the variable. When called with no arguments, the procedure returns the current value of the
240variable. When called with an argument, then the variable is set to the value of that argument.
241C and C++ style comments are supported. Variables declared as {{const}}
242will generate normal Scheme variables, bound to the initial value of the variable.
243
244Function-, member-function and constructor/destructor definitions may be preceded by the {{___safe}}
245qualifier, which marks the function as (possibly) performing a callback into Scheme. If a wrapped function
246calls back into Scheme code, and {{___safe}} has not been given very strange and hard to debug
247problems will occur.
248
249Functions and member functions prefixed with {{___discard}} and a result type that maps to
250a Scheme string ({{c-string}}), will have their result type changed to {{c-string*}} instead.
251
252Constants (as declared by {{#define}} or {{enum}}) are not visible outside of the current
253Compilation units unless the {{export_constants}} pseudo declaration has been used.
254Only numeric or character constants are directly supported.
255
256Function-arguments may be preceded by {{___in}}, {{___out}} and {{___inout}}
257qualifiers to specify values that are passed by reference to a function, or returned by
258reference. Only basic types (booleans, numbers and characters) can be passed using this method.
259During the call a pointer to a temporary piece of storage containing the initial value (or a random
260value, for {{___out}} parameters) will
261be allocated and passed to the wrapped function. This piece of storage is subject to
262garbage collection and will move, should a callback into Scheme occur that triggers
263a garbage collection. Multiple {{__out}} and {{___inout}} parameters will
264be returned as multiple values, preceded by the normal return value of thhe function
265(if not {{void}}). Here is a simple example:
266
267 #>!
268 #ifndef CHICKEN
269 #include <math.h>
270 #endif
271
272 double modf(double x, ___out double *iptr);
273 <#
274
275 (let-values ([(frac int) (modf 33.44)])
276   ...)
277
278Function-arguments may be preceded by {{___length(ID)}}, where {{ID}} designates
279the name of another argument that must refer to a number vector or string argument. The value
280of the former argument will be computed at run-time and thus can be omitted:
281
282 #>!
283 (require-extension srfi-4)
284
285 double sumarray(double *arr, ___length(arr) int len)
286 {
287   double sum = 0;
288
289   while(len--) sum += *(arr++);
290
291   return sum;
292 }
293 <#
294
295 (print (sumarray (f64vector 33 44 55.66)))
296
297The length variable may be positioned anywhere in the argument list. Length markers may only be
298specified for arguments passed as SRFI-4 byte-vectors, byte-vectors (as provided by the
299{{lolevel}} library unit) or strings.
300
301Structure and union definitions containing actual field declarations generate getter procedures
302(and SRFI-17 setters when
303declared {{___mutable}} or the {{mutable_fields}} pseudo declaration has been used)
304The names of these procedures are computed by concatenating the struct (or union) name,
305a hyphen ({{"-"}}) and the field name. Structure definitions with fields may not be used in positions where a type
306specifier is normally expected. The field accessors operate on struct/union pointers only.
307Additionally a zero-argument procedure named {{make-<structname>}} will be generated
308that allocates enough storage to hold an instance of the structure (or union).
309Prefixing the definition with {{___abstract}} will omit the creation procedure.
310
311 #>!
312 struct My_struct { int x; ___mutable float y; };
313
314 typedef struct My_struct My_struct;
315
316 My_struct *make_struct(int x, float y)
317 {
318   My_struct *s = (My_struct *)malloc(sizeof(My_struct));
319   s->x = x;
320   s->y = y;
321   return s;
322 }
323 <#
324
325will generate the following definitions:
326
327 (make-My_struct) -> PTR
328 (My_struct-x PTR) -> INT
329 (My_struct-y PTR) -> FLOAT
330 (set! (My_struct-y PTR) FLOAT)
331 (make_struct INT FLOAT) -> PTR
332
333Nested structs or unions are not supported (but pointers to nested structs/unions are).
334
335All specially handled tokens preceded with {{___}} are defined as C macros in the
336headerfile {{chicken.h}} and will usually expand into nothing, so they don't
337invalidate the processed source code.
338
339C++ {{namespace}} declarations of the form {{namespace NAME @{ ... @}}} recognized but will
340be completely ignored.
341
342Keep in mind that this is not a fully general C/C++ parser. Taking an arbitrary headerfile and feeding
343it to CHICKEN will in most cases not work or generate riduculuous amounts of code. This FFI
344facility is for carefully written headerfiles, and for declarations directly embedded into
345Scheme code.
346
347=== Pseudo declarations
348
349Using the {{___declare(DECL, VALUE)}} form, pseudo declarations can be embedded into
350processed C/C++ code to provide additional control over the wrapper generation. Pseudo declarations
351will be ignored when processed by the system's C/C++ compiler.
352
353 abstract [values: <string>]
354
355Marks the C++ class given in {{<string>}} as being abstract, i.e. no constructor will be defined. Alternatively, a class definition may be prefixed with {{___abstract}}.
356
357 class_finalizers [values: yes, no]
358
359Automatically generates calls to {{set-finalizer!}} so that any unused references to instances of subsequently defined C++ class wrappers will be destroyed. This should be used with care: if the embedded C++ object which is represented by the reclaimed TinyCLOS instance is still in use in foreign code, then unpredictable things will happen.
360
361 mutable_fields [values: yes, no]
362
363Specifies that all struct or union fields should generate setter procedures (the default is to generate only setter procedures for fields declared {{___mutable}}).
364
365 destructor_name [values: <string>]
366
367Specifies an alternative name for destructor methods (the default is {{destroy}}.
368
369 export_constants [values: yes (default), no]
370
371Define a global variable for constant-declarations (as with {{#define}} or {{enum}}), making the constant available outside the current compilation unit. Use the values {{yes}}/{{1}} for switching constant export on, or {{no}}/{{0}} for switching it off.
372
373 exception_handler [values: <string>]
374
375Defines C++ code to be executed when an exception is triggered inside a C++ class member function. The code should be one or more {{catch}} forms that perform any actions that should be taken in case an exception is thrown by the wrapped member function:
376
377 #>!
378 ___declare(exception_handler, "catch(...) { return 0; }")
379
380 class Foo {
381  public:
382   Foo *bar(bool f) { if(f) throw 123; else return this; }
383 };
384 <#
385
386 (define f1 (make <Foo>))
387 (print (bar f1 #f))
388 (print (bar f1 #t))
389
390will print {{<Foo>}} and {{#f}}, respectively.
391
392 full_specialization [values: yes, no]
393
394Enables ''full specialization'' mode. In this mode all wrappers for functions, member functions and static member functions are created as fully specialized TinyCLOS methods. This can be used to handle overloaded C++ functions properly. Only a certain set of foreign argument types can be mapped to TinyCLOS classes, as listed in the following table:
395
396 char             <char>
397 bool             <bool>
398 c-string         <string>
399 unsigned-char    <exact>
400 byte             <exact>
401 unsigned-byte    <exact>
402 [unsigned-]int   <exact>
403 [unsigned-]short <exact>
404 [unsigned-]long  <integer>
405 [unsigned-]integer     <integer>
406 float            <inexact>
407 double           <inexact>
408 number           <number>
409 (enum _)char     <exact>
410 (const T)char    (as T)
411 (function ...)   <pointer>
412 c-pointer        <pointer>
413 (pointer _)      <pointer>
414 (c-pointer _)    <pointer>
415 u8vector         <u8vector>
416 s8vector         <s8vector>
417 u16vector        <u16vector>
418 s16vector        <s16vector>
419 u32vector        <u32vector>
420 s32vector        <s32vector>
421 f32vector        <f32vector>
422 f64vector        <f64vector>
423
424All other foreign types are specialized as {{<top>}}.
425
426Full specialization can be enabled globally, or only for sections of code by
427enclosing it in
428
429 ___declare(full_specialization, yes)
430 ...
431 int foo(int x);
432 int foo(char *x);
433 ...
434 ___declare(full_specialization, no)
435
436Alternatively, member function definitions may be prefixed by {{___specialize}} for specializing
437only specific members.
438
439 prefix [values: <string>]
440
441Sets a prefix that should be be added to all generated Scheme identifiers. For example
442
443 ___declare(prefix, "mylib:")
444 #define SOME_CONST     42
445
446would generate the following code:
447
448 (define-constant mylib:SOME_CONST 42)
449
450To switch prefixing off, use the values {{no}} or {{0}}. Prefixes are not applied to
451Class names.
452
453 rename [value: <string>]
454
455Defines to what a certain C/C++ name should be renamed. The value for this declaration should have the form {{"<c-name>;<scheme-name>"}}, where {{<c-name>}} specifies the C/C++ identifier occurring in the parsed text and {{<scheme-name>}} gives the name used in generated wrapper code.
456
457 scheme [value: <string>]
458
459Embeds the Scheme expression {{<string>}} in the generated Scheme code.
460
461 substitute [value: <string>]
462
463Declares a name-substitution for all generated Scheme identifiers. The value for this declaration should be a string containing a regular expression and a replacement string (separated by the {{;}} character):
464
465 ___declare(substitute, "^SDL_;sdl:")
466
467 extern void SDL_Quit();
468
469generates
470
471 (define sdl:Quit
472   (foreign-lambda integer "SDL_Quit") )
473
474 transform [values: <string>]
475
476Defines an arbitrary transformation procedure for names that match a given regular expression. The value should be a string containing a regular expression and a Scheme expression that evaluates to a procedure of one argument. If the regex matches, the procedure will be called at compile time with the match-result (as returned by {{string-match}}) and should return a string with the desired transformations applied:
477
478 (require-for-syntax 'srfi-13)
479
480 #>!
481 ___declare(transform, "([A-Z]+)_(.*);(lambda (x) (string-append (cadr x) \"-\" (string-downcase (caddr x))))")
482
483 void FOO_Bar(int x) { return x * 2; }
484 <#
485
486 (print (FOO-bar 33))
487
488 default_renaming [value: <string>]
489
490Chooses a standard name-transformation, converting underscores ({{_}}) to hyphens ({{-}}) and transforming ''CamelCase'' into ''camel-case''. All uppercase characters are also converted to lowercase. The result is prefixed with the argument string (equivalent to the {{prefix}} pseudo declaration).
491
492 type [value: <string>]
493
494Declares a foreign type transformation, similar to {{define-foreign-type}}. The value should be a list of two to four items, separated by the {{;}} character: a C typename, a Scheme foreign type specifier and optional argument- and result-value conversion procedures.
495
496 ;;;; foreign type that converts to unicode (assumes 4-byte wchar_t):
497 ;
498 ; - Note: this is rather kludgy and is only meant to demonstrate the `type'
499 ;         pseudo-declaration
500
501 (require-extension srfi-4)
502
503 (define mbstowcs (foreign-lambda int "mbstowcs" nonnull-u32vector c-string int))
504
505 (define (str->ustr str)
506   (let* ([len (string-length str)]
507          [us (make-u32vector (add1 len) 0)] )
508     (mbstowcs us str len)
509     us) )
510
511 #>!
512 ___declare(type, "unicode;nonnull-u32vector;str->ustr")
513
514 static void foo(unicode ws)
515 {
516   printf("\"%ls\"\n", ws);
517 }
518 <#
519
520 (foo "this is a test!")
521
522 opaque [value: <string>]
523
524Similar to {{type}}, but provides automatic argument- and result conversions to wrap a value into a structure:
525
526 #>?
527 ___declare(opaque, "myfile;(pointer \"FILE\")")
528
529 myfile fopen(char *, char *);
530 <#
531
532 (fopen "somefile" "r")   ==> <myfile>
533
534{{___declare(opaque, "TYPENAME;TYPE")}} is basically equivalent to
535{{___declare(type, "TYPENAME;TYPE;TYPE->RECORD;RECORD->TYPE")}} where
536{{TYPE->RECORD}} and {{RECORD->TYPE}} are compiler-generated conversion
537functions that wrap objects of type {{TYPE}} into a record and back.
538
539=== Grammar
540
541The parser understand the following grammar:
542
543 PROGRAM = PPCOMMAND
544         | DECLARATION ";"
545 
546 PPCOMMAND = "#define" ID [TOKEN ...]
547           | "#ifdef" ID
548           | "#ifndef" ID
549           | "#else"
550           | "#endif"
551           | "#undef" ID
552           | "#error" TOKEN ...
553           | "#include" INCLUDEFILE
554           | "#import" INCLUDEFILE
555           | "#pragma" TOKEN ...
556 
557 DECLARATION = FUNCTION
558             | VARIABLE
559             | ENUM
560             | TYPEDEF
561             | CLASS
562             | CONSTANT
563             | STRUCT
564             | NAMESPACE
565             | "___declare" "(" PSEUDODECL "," <tokens> ")"
566 
567 STRUCT = ("struct" | "union") ID ["{" {["___mutable"] TYPE {"*"} ID {"," {"*"} ID}} "}]
568 
569 NAMESPACE = "namespace" ID "{" DECLARATION ... "}"
570 
571 INCLUDEFILE = "\"" ... "\""
572             | "<" ... ">"
573 
574 FUNCTION = {"___safe" | "___specialize" | "___discard"} [STORAGE] TYPE ID "(" ARGTYPE "," ... ")" [CODE]
575          | {"___safe" | "___specialize" | "___discard"} [STORAGE] TYPE ID "(" "void" ")" [CODE]
576 
577 ARGTYPE = [IOQUALIFIER] TYPE [ID ["[" ... "]"]]
578 
579 IOQUALIFIER = "___in" | "___out" | "___inout" | LENQUALIFIER
580 
581 LENQUALIFIER = "___length" "(" ID ")"
582 
583 VARIABLE = [STORAGE] ENTITY ["=" INITDATA]
584 
585 ENTITY = TYPE ID ["[" ... "]"]
586 
587 STORAGE = "extern" | "static" | "volatile" | "inline"
588 
589 CONSTANT = "const" TYPE ID "=" INITDATA
590 
591 PSEUDODECL = "export_constants"
592            | "prefix"
593            | "substitute"
594            | "abstract"
595            | "type"
596            | "scheme"
597            | "rename"
598            | "transform"
599            | "full_specialization"
600            | "destructor_name"
601            | "class_finalizers"
602            | "exception_handler"
603            | "mutable_fields"
604 
605 ENUM = "enum" "{" ID ["=" (NUMBER | ID)] "," ... "}"
606 
607 TYPEDEF = "typedef" TYPE ["*" ...] [ID]
608 
609 TYPE = ["const"] BASICTYPE [("*" ... | "&" | "<" TYPE "," ... ">" | "(" "*" [ID] ")" "(" TYPE "," ... ")")]
610 
611 BASICTYPE = ["unsigned" | "signed"] "int"
612           | ["unsigned" | "signed"] "char"
613           | ["unsigned" | "signed"] "short" ["int"]
614           | ["unsigned" | "signed"] "long" ["int"]
615           | ["unsigned" | "signed"] "___byte"
616           | "size_t"
617           | "float"
618           | "double"
619           | "void"
620           | "bool"
621           | "___bool"
622           | "___scheme_value"
623           | "___scheme_pointer"
624           | "___byte_vector"
625           | "___pointer" TYPE "*"
626           | "C_word"
627           | "___fixnum"
628           | "___number"
629           | "___symbol"
630           | "___u32"
631           | "___s32"
632           | "___s64"
633           | "__int64"
634           | "int64_t"
635           | "struct" ID
636           | "union" ID
637           | "enum" ID
638           | ID
639 
640 CLASS = ["___abstract"] "class" ID [":" [QUALIFIER] ID "," ...] "{" MEMBER ... "}"
641 
642 MEMBER = [QUALIFIER ":"] ["virtual"] (MEMBERVARIABLE | CONSTRUCTOR | DESTRUCTOR | MEMBERFUNCTION)
643 
644 MEMBERVARIABLE = TYPE ID ["=" INITDATA]
645 
646 MEMBERFUNCTION = {"___safe" | "static" | "___specialize" | "___discard"} TYPE ID "(" ARGTYPE "," ... ")" ["const"] ["=" "0"] [CODE]
647                | {"___safe" | "static" | "___specialize" | "___discard"} TYPE ID "(" "void" ")" ["const"] ["=" "0"] [CODE]
648 
649 CONSTRUCTOR = ["___safe"] ["explicit"] ID "(" ARGTYPE "," ... ")" [BASECONSTRUCTORS] [CODE]
650 
651 DESTRUCTOR = ["___safe"] "~" ID "(" ["void"] ")" [CODE]
652 
653 QUALIFIER = ("public" | "private" | "protected")
654 
655 NUMBER = <a C integer or floating-point number, in decimal, octal or hexadecimal notation>
656 
657 INITDATA = <everything up to end of chunk>
658 
659 BASECONSTRUCTORS = <everything up to end of chunk>
660 
661 CODE = <everything up to end of chunk>
662
663The following table shows how argument-types are translated:
664
665 [unsigned] char          char
666 [unsigned] short         [unsigned-]short
667 [unsigned] int           [unsigned-]integer
668 [unsigned] long          [unsigned-]long
669 ___u32                   unsigned-integer32
670 ___s32                   integer32
671 ___s64                   integer64
672 int64_t                  integer64
673 __int64                  integer64
674 float                    float
675 double                   double
676 size_t                   unsigned-integer
677 bool                     int
678 ___bool                  int
679 ___fixnum                int
680 ___number                number
681 ___symbol                symbol
682 ___scheme_value          scheme-object
683 C_word                   scheme-object
684 ___scheme_pointer        scheme-pointer
685 char *                   c-string
686 signed char *            s8vector
687 [signed] short *         s16vector
688 [signed] int *           s32vector
689 [signed] long *          s32vector
690 unsigned char *          u8vector
691 unsigned short *         u16vector
692 unsigned int *           u32vector
693 unsigned long *          u32vector
694 float *                  f32vector
695 double *                 f64vector
696 ___byte_vector           byte-vector
697 CLASS *                  (instance CLASS <CLASS>)
698 CLASS &                  (instance-ref CLASS <CLASS>)
699 TYPE *                   (pointer TYPE)
700 TYPE &                   (ref TYPE)
701 TYPE<T1, ...>            (template TYPE T1 ...)
702 TYPE1 (*)(TYPE2, ...)    (function TYPE1 (TYPE2 ...))
703
704
705The following table shows how result-types are translated:
706
707 void                     void
708 [unsigned] char          char
709 [unsigned] short         [unsigned-]short
710 [unsigned] int           [unsigned-]integer
711 [unsigned] long          [unsigned-]long
712 ___u32                   unsigned-integer32
713 ___s32                   integer32
714 ___s64                   integer64
715 int64_t                  integer64
716 __int64                  integer64
717 float                    float
718 double                   double
719 size_t                   unsigned-integer
720 bool                     bool
721 ___bool                  bool
722 ___fixnum                int
723 ___number                number
724 ___symbol                symbol
725 ___scheme_value          scheme-object
726 char *                   c-string
727 TYPE *                   (pointer TYPE)
728 TYPE &                   (ref TYPE)
729 TYPE<T1, ...>            (template TYPE T1 ...)
730 TYPE1 (*)(TYPE2, ...)    (function TYPE1 (TYPE2 ...))
731 CLASS *                  (instance CLASS <CLASS>)
732 CLASS &                  (instance-ref CLASS <CLASS>)
733
734The {{___pointer}} argument marker disables automatic simplification of pointers to numbers: normally
735arguments of type {{int *}} are handled as SRFI-4 {{s32vector}} number vectors. To force treatment
736as a pointer argument, precede the argument type with {{___pointer}}.
737
738
739=== C notes
740
741Foreign variable definitions for macros are not exported from the current compilation unit, but
742definitions for C variables and functions are.
743
744{{foreign-parse}} does not embed the text into
745the generated C file, use {{foreign-declare}} for that (or even better, use the {{#>! ... <#}} syntax
746which does both).
747
748Functions with variable number of arguments are not supported.
749
750=== C++ notes
751
752Each C++ class defines a TinyCLOS class, which is a subclass of {{<c++-object>}}. Instances of this class
753contain a single slot named {{this}}, which holds a pointer to a heap-allocated C++ instance.
754The name of the TinyCLOS class is obtained by putting the C++ classname between angled brackets ({{<...>}}).
755TinyCLOS classes are not seen by C++ code.
756
757The C++ constructor is invoked by the {{initialize}} generic, which accepts as many arguments
758as the constructor. If no constructor is defined, a default-constructor will be provided taking no arguments.
759To allow creating class instances from pointers created in foreign code, the {{initialize}}
760generic will optionally accept an arguments list of the form {{'this POINTER}}, where {{POINTER}}
761is a foreign pointer object. This will create a TinyCLOS instance for the given C++ object.
762
763To release the storage allocated for a C++ instance invoke the {{destroy}} generic
764(the name can be changed by using the {{destructor_name}} pseudo declaration).
765
766Static member functions are wrapped in a Scheme procedure named {{<class>::<member>}}.
767
768Member variables and non-public member functions are ignored.
769
770Virtual member functions are not seen by C++ code. Overriding a virtual member function with a TinyCLOS
771method will not work when the member 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 thrown beyond an invocation
776of C++ by Scheme code.
777
778== Authors
779
780[[/users/felix winkelmann|felix winkelmann]]
781
782== License
783
784 Copyright (c) 2000-2007, Felix L. Winkelmann
785 All rights reserved.
786
787 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
788 conditions are met:
789
790   Redistributions of source code must retain the above copyright notice, this list of conditions and the following
791     disclaimer.
792   Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
793     disclaimer in the documentation and/or other materials provided with the distribution.
794   Neither the name of the author nor the names of its contributors may be used to endorse or promote
795     products derived from this software without specific prior written permission.
796
797 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
798 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
799 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
800 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
801 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
802 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
803 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
804 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
805 POSSIBILITY OF SUCH DAMAGE.
806
807== Version History
808
809; 1.99.2 : use {{regex}} as extension, not unit (for CHICKEN 4.6.3)
810; 1.97 : removed {{-host}} option from setup script
811; 1.96 : fixed bug in warning message that caused {{sprintf}} expansion to fail
812; 1.91 : fixed number parsing bug [Thanks to Shawn Rutledge]
813; 1.9 : removed use of obsolete reader hack
814; 1.8 : removed deprecated {{___callback}}
815; 1.7 : added {{chicken-wrap}} tool
816; 1.6 : fixed error in handling of base constructors [Thanks to Carlos Pita]
817; 1.5 : added {{foreign-include-path}} [this missing interface was reported by Carlos Pita]
818; 1.4 : fixed bug in parser that ignored preprocessor commands in some situations [Thanks to Tony Sidaway]
819; 1.3 : struct-member write-access uses SRFI-17 {{set!}}
820; 1.2 : handles {{#define ID (NUM)}} and shows output in compiler with {{-debug F}}
821; 1.1 : simplified .setup script
822; 1.0 : moved from base distribution into separate extension
Note: See TracBrowser for help on using the repository browser.