Next: Defining New Wrapped Types, Up: A More Detailed Example [Contents][Index]
Inside the wrapset specification file, the first thing you have to do is create the wrapset class (for a detailed explanation, refer to see Wrapsets). But before that, you have to tell Guile that you’ll use the GOOPS and G-Wrap modules. So the most trivial wrapper module possible would look something like this:
(use-modules (oop goops) (g-wrap) (g-wrap guile)) (define-class <miscutils-wrapset> (<gw-guile-wrapset>) #:id 'miscutils) (define-method (initialize (ws <miscutils-wrapset>) initargs) (next-method ws (append '(#:module (miscutils)) initargs)))
Note how the Guile module that the wrapset should reside in is passed
to the next-method
of initialize
as a keyword argument.
However, this wrapset won’t let you do much. In particular, a newly
created wrapset 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 #:dependencies
keyword argument to
the class definition:
(define-class <miscutils-wrapset> (<gw-guile-wrapset>) #:id 'miscutils #:dependencies '(standard))
Now you can start wrapping functions using the default set of wrapped
types with calls to wrap-function!
. To wrap
join_strings
and seconds_since
, you would
want to say something like this:
(define-method (initialize (ws <miscutils-wrapset>) initargs) (next-method ws (append '(#:module (miscutils)) initargs)) (wrap-function! ws #:name 'join_strings #:returns 'mchars #:c-name "join_strings" #:arguments '((mchars a) (mchars b)) #:description "Return a string consisting of a followed by b.") (wrap-function! ws #:name 'seconds-since-dow #:returns 'double #:c-name "seconds_since_dow" #:arguments '((uint day-of-week)) #:description "Given day-of-week (ranging 1-7), return elapsed time since then."))
wrap-function!
’s arguments should be quite obvious. They are
detailed in See Wrapping a C Function.
Actually, the example given above won’t work because specifying
mchars
(roughly G-Wrap’s type for char*
, see C Types Provided in the Standard Wrapset) 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 type options
for string type arguments and return values: caller-owned
and
callee-owned
. The "m" in mchars
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 this function is:
(wrap-function! ws #:name 'join-strings #:returns '(mchars caller-owned) #:c-name "join_strings" #:arguments '(((mchars caller-owned) a) ((mchars caller-owned) b)) #:description "Return a string consisting of a followed by b.")
At this point, we have a wrapset 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. You could use it like this:
guile> (use-modules (miscutils)) guile> (join-strings "out" "let") "outlet" guile> (seconds-since-dow 1) 3099.232 guile>
Next: Defining New Wrapped Types, Up: A More Detailed Example [Contents][Index]