Copyright (C) 2000-2012 |
GNU Info (g-wrap.info)Creating a Wrapper ModuleCreating 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 |