source: project/wiki/eggref/4/bind @ 27018

Last change on this file since 27018 was 27018, checked in by svnwiki, 9 years ago

Anonymous wiki edit for IP [50.0.146.157]:

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