GNU Info

Info Node: (g-wrap.info)Defining basic Scheme/C types

(g-wrap.info)Defining basic Scheme/C types


Prev: Extending g-wrap and porting it to other Scheme implementations Up: Extending g-wrap and porting it to other Scheme implementations
Enter node , (file) or (file)node

Defining 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