Copyright (C) 2000-2012 |
GNU Info (g-wrap.info)Defining basic Scheme/C typesDefining basic Scheme/C types ============================= For calling C functions from Scheme, a mechanism is needed for checking the type of Scheme values, converting Scheme values to C values, and converting C values to Scheme values. The function `make-c-type' is used for making a type-description object which represents how to do this for a given Scheme implementation. - Function: make-c-type c-name fn-convert-to-scm fn-convert-from-scm fn-scm-is-a C-NAME is a string indicating the name of the type in C. FN-CONVERT-TO-SCM is a function which generates an expression to convert a C value of this type to a Scheme value. FN-CONVERT-FROM-SCM is a function which generates an expression convert a Scheme value into a C value of this type. FN-SCM-IS-A is a function which generates a check for whether a Scheme value can be converted to this type of C value. It returns `0' for false and a non-zero value for true. The "expressions" generated for output to C code are strings, or lists or trees of strings. - Function: add-new-type scheme-sym the-type Associates a type-description object, such as that generated by `make-c-type', to a symbol so that symbol may be used to refer to a type in a parameter of a function such as `(new-function ...)'. - Function: add-type scheme-sym c-type-str fn-to-scm fn-from-scm fn-isa This both defines the type-description and assigns it to a symbol. A simple example of how an integer type corresponding to an immediate number in the Guile might be defined: (add-type 'int "int" ;fn-convert-to-scm (lambda (x) (list "SCM_MAKINUM(" x ")")) ;fn-convert-from-scm (lambda (x) (list "SCM_INUM(" x ")")) ;fn-scm-is-a (lambda (x) (list "SCM_INUMP(" x ")"))) An example of how type `void' (used for specifying no return value for a function) might be defined for the Guile interpreter. (add-type 'void "void" ;fn-convert-to-scm (lambda (x) "SCM_UNSPECIFIED") ;fn-convert-from-scm (lambda (x) "(void)") ;fn-scm-is-a (lambda (x) 1)) - Function: get-type scheme-sym Returns the type-description object associated with a symbol. - Function: make-complex-c-type c-name fn-convert-to-scm fn-convert-from-scm fn-scm-is-a c-cleanup-arg-default? c-cleanup-ret-default? fn-c-cleanup WARNING: This function, and the related "cleanup" system should be considered highly experimental and subject to change up until at least 1.X of g-wrap is released. Don't use this unless you're willing to have to re-write everything that depends on it later. It is currently being tested in GnuCash, but isn't claimed to be ready for prime-time. Further, in it's final incarnation, it will probably be a more general mechanism... This function creates a new g-wrap type corresponding to the C-type C-NAME. Unlike NEW-TYPE, this function does not have any affect unless you use ADD-NEW-TYPE to tell g-wrap to add the type to its list of known types. The parameters have the following purposes: C-NAME the name of the type as far as C is concerned. FN-CONVERT-TO-SCM a function returning the C code to be used to convert this type from a C representation to a Scheme representation. FN-CONVERT-FROM-SCM a function returning the C code to be used to convert this type from a Scheme representation to a C representation. FN-SCM-IS-A a function returning the C code to be used to test if a Scheme object is of this type. C-CLEANUP-ARG-DEFAULT? should arguments of this type have their C representations (the ones created for the purpose of the C-side function call) be cleaned up just after the call by default? C-CLEANUP-RET-DEFAULT? should return values of this type have their C representations (the ones returned by a C-side function call) cleaned up just after they are converted to Scheme, but before the wrapper code returns to Scheme by default? FN-C-CLEANUP a function returning the C code to be used to clean up (destroy, delete, free, whatever) C representations of this type. To understand what the cleanup-related arguments do, consider a typical wrapper call-sequence. First the Scheme wrapper function is called. Then all of the Scheme arguments are converted to C representations using the convert-to-scm functions, then the C function is called with these arguments, and finally, the return value, if any is converted from its C representation back to a Scheme value and returned from the wrapper. The cleanup arguments control the final disposition of the C representations of the given type when used as arguments and return values. If an argument is marked as 'cleanup, then just after the C function returns, the argument will be cleaned up using the c-cleanup function provided by FN-C-CLEANUP. The same thing happens to the C representation of the return value just after it has been converted to a Scheme representation, and just before the wrapper returns. An argument or return value is considered to be "marked as 'cleanup" if either C-CLEANUP-ARG-DEFAULT? or C-CLEANUP-RET-DEFAULT? is not #f respectively, or if the argument or return value is marked 'cleanup in the options to NEW-FUNCTION. For more details see Note: Defining a new function. Deciding when cleanup is appropriate depends on the semantics of both the type in question and of a given C function. What's really at issue here is the "ownership" of the C level data involved. For example, imagine you have a C function that takes a string pointer as an argument and expects that at the time of the call, it becomes the "owner" of that pointer, and perhaps it takes that pointer and stores it in a hash table for later use. If that particular argument were marked as 'cleanup in g-wrap, as soon as the C function was called, g-wrap would arrange for it to be freed, leaving the pointer in the hash table dangling. So for this particular hypothetical function, the argument in question needs to be marked as 'no-cleanup, either as the type default (probably not a good idea for strings in general), or in the NEW-FUNCTION declaration. For more details see Note: Defining a new function. Similar considerations apply to return values. If you had a C function that returned a constant string pointer from some static or global table, then it wouldn't be appropriate for the return value to be marked 'cleanup. Conversely there may also be types for which 'no-cleanup makes the most sense as a default, and then 'cleanup would need to be used in calls to NEW-FUNCTION occasionally. For more details see Note: Defining a new function. Example: (add-new-type 'bar (make-complex-c-type "bar" ;; fn-convert-to-scm (lambda (x) (list "bar2scm(" x ")")) ;; fn-convert-from-scm (lambda (x) (list "scm2bar(" x ")")) ;; fn-scm-is-a (lambda (x) (list "bar_p(" x ")")) ;; c-cleanup-arg-default? #t ;; c-cleanup-ret-default? #t ;; fn-c-cleanup (lambda (x) (list "free_bar(" x ")")))) automatically generated by info2www version 1.2.2.9 |