GNU Info

Info Node: (g-wrap.info)Creating a Wrapper Module

(g-wrap.info)Creating a Wrapper Module


Next: Defining New Wrapped Types Prev: A More Detailed Example. Up: Usage
Enter node , (file) or (file)node

Creating a Wrapper Module
=========================

Inside the wrapper module specification file, the first thing you have
to do is create the wrapper module.  This is handled with a call to the
function `gw:new-module', but before that, you have to tell Guile that
you want to use g-wrap functions with a call to `(use-modules
(g-wrap))'.  So the most trivial wrapper module possible would look
something like this:

       (let ((mod (gw:new-module "miscutils")))
         #t)

However, this module won't let you do much.  In particular, a newly
created wrapper module doesn't know about any wrapped types.  In general
you'll probably want to be able to use the standard set of g-wrap
wrapped types which include support for int, double, strings, etc.  If
so, then you need to add a call to `gw:module-depends-on' like so:

       (let ((mod (gw:new-module "miscutils")))
         (gw:module-depends-on mod "gw-runtime")
         #t)

Now you can start wrapping functions using the default set of wrapped
types with calls to `gw:wrap-function'.  To wrap `join_strings' and
`seconds_since', you would want to say something like this:

       (let ((mod (gw:new-module "miscutils")))
     
         (gw:module-depends-on mod "gw-runtime")
     
         (gw:wrap-function
          mod
          'join_strings
          '<gw:char*> "join_strings" '((<gw:char*> a) (<gw:char*> b))
          "Return a string consisting of a followed by b.")
     
         (gw:wrap-function
          mod
          'seconds-since-dow
          '<gw:double> "seconds_since_dow" '((<gw:unsigned-int> day-of-week))
          "Given day-of-week (ranging 1-7), return elapsed time since then."))

`gw:wrap-function''s arguments in order are

  1. the module to which the function wrapper should be added.

  2. the symbol which should be bound to the wrapped function in Scheme
     at runtime.

  3. the symbol naming the g-wrap wrapped type of the C function result.

  4. a string giving the C function's name.

  5. a list of the C function's arguments where each element is of the
     form (g-wrapped-type arg-name-symbol).

  6. a string describing the function.


Actually, the example given above won't work because g-wrap has no
definition for char*'s.  There is no <gw:char*> wrapped type.  The
reason is that specifying char* alone doesn't provide enough information
about the allocation semantics of the argument or return value.  G-wrap
needs to know whether a char* argument that's passed in to a function
should be considered to be "owned" by the function after the C function
returns, or should be considered caller owned, and hence safe for
deletion if appropriate.  So g-wrap requires you to be explicit, and
provides two different types for string type arguments and return
values: `<gw:m-chars-caller-owned>' and `<gw:m-chars-callee-owned>'.
The "m" stands for `malloc', since it's conceivable that for some C
functions, the argument or result might need to be allocated/freed via
some other mechanism.

So, for our example API, let's presume that `join_strings' takes two
strings that are owned by the caller and returns a newly allocated
string that will also be owned by the caller.  Given that, the correct
way to wrap our example API would be:

       (let ((mod (gw:new-module "miscutils")))
     
         (gw:module-depends-on mod "gw-runtime")
     
         (gw:wrap-function
          mod
          'join-strings
          '<gw:m-chars-caller-owned> "join_strings"
          '((<gw:m-chars-caller-owned> a) (<gw:m-chars-caller-owned> b))
          "Return a string consisting of a followed by b.")
     
         (gw:wrap-function
          mod
          'seconds-since-dow
          '<gw:double> "seconds_since_dow" '((<gw:unsigned-int> day-of-week))
          "Given day-of-week (ranging 1-7), return elapsed time since then."))

At this point, we have a wrapper module named "miscutils" that wraps our
two C functions so that when the wrapper module's C code is generated,
compiled, and then loaded back into Guile, we should be able to call
these C functions normally.  Presuming you set miscutils up as a g-wrap
module of that name, you could use it like this:


       guile> (use-modules (miscutils))
       guile> (join-strings "out" "let")
       "outlet"
       guile> (seconds-since-dow 1)
       3099.232
       guile>


automatically generated by info2www version 1.2.2.9