Software: Apache/2.0.54 (Fedora). PHP/5.0.4 uname -a: Linux mina-info.me 2.6.17-1.2142_FC4smp #1 SMP Tue Jul 11 22:57:02 EDT 2006 i686 uid=48(apache) gid=48(apache) groups=48(apache) Safe-mode: OFF (not secure) /usr/share/doc/swig-1.3.24/Manual/ drwxr-xr-x |
Viewing file: Select action/file-type: 18 SWIG and Guile
This section details guile-specific support in SWIG. 18.1 Meaning of "Module"There are three different concepts of "module" involved, defined separately for SWIG, Guile, and Libtool. To avoid horrible confusion, we explicitly prefix the context, e.g., "guile-module". 18.2 Using the SCM or GH Guile APIThe guile module can currently export wrapper files that use the guile GH interface or the SCM interface. This is controlled by an argument passed to swig. The "-gh" argument causes swig to output GH code, and the "-scm" argument causes swig to output SCM code. Right now the "-scm" argument is the default. The "-scm" wrapper generation assumes a guile version >= 1.6 and has several advantages over the "-gh" wrapper generation including garbage collection and GOOPS support. The "-gh" wrapper generation can be used for older versions of guile. The guile GH wrapper code generation is depreciated and the SCM interface is the default. The SCM and GH interface differ greatly in how they store pointers and have completely different run-time code. See below for more info. The GH interface to guile is deprecated. Read more about why in the Guile manual. The idea of the GH interface was to provide a high level API that other languages and projects could adopt. This was a good idea, but didn't pan out well for general development. But for the specific, minimal uses that the SWIG typemaps put the GH interface to use is ideal for using a high level API. So even though the GH interface is depreciated, SWIG will continue to use the GH interface and provide mappings from the GH interface to whatever API we need. We can maintain this mapping where guile failed because SWIG uses a small subset of all the GH functions which map easily. All the guile typemaps like typemaps.i and std_vector.i will continue to use the GH functions to do things like create lists of values, convert strings to integers, etc. Then every language module will define a mapping between the GH interface and whatever custom API the language uses. This is currently implemented by the guile module to use the SCM guile API rather than the GH guile API. For example, here are some of the current mapping file for the SCM API #define gh_append2(a, b) scm_append(scm_listify(a, b, SCM_UNDEFINED)) #define gh_apply(a, b) scm_apply(a, b, SCM_EOL) #define gh_bool2scm SCM_BOOL #define gh_boolean_p SCM_BOOLP #define gh_car SCM_CAR #define gh_cdr SCM_CDR #define gh_cons scm_cons #define gh_double2scm scm_make_real ... This file is parsed by SWIG at wrapper generation time, so every reference to a gh_ function is replaced by a scm_ function in the wrapper file. Thus the gh_ function calls will never be seen in the wrapper; the wrapper will look exactly like it was generated for the specific API. Currently only the guile language module has created a mapping policy from gh_ to scm_, but there is no reason other languages (like mzscheme or chicken) couldn't also use this. If that happens, there is A LOT less code duplication in the standard typemaps. 18.3 LinkageGuile support is complicated by a lack of user community cohesiveness, which manifests in multiple shared-library usage conventions. A set of policies implementing a usage convention is called a linkage. 18.3.1 Simple LinkageThe default linkage is the simplest; nothing special is done. In this case the functionSWIG_init() is exported. Simple linkage
can be used in several ways:
If you want to include several SWIG modules, you would need to rename
18.3.2 Passive LinkagePassive linkage is just like simple linkage, but it generates an initialization function whose name is derived from the module and package name (see below). You should use passive linkage rather than simple linkage when you are using multiple modules. 18.3.3 Native Guile Module LinkageSWIG can also generate wrapper code that does all the Guile module
declarations on its own if you pass it the The module name is set with the You can use this linkage in several ways:
18.3.4 Old Auto-Loading Guile Module LinkageGuile used to support an autoloading facility for object-code
modules. This support has been marked deprecated in version 1.4.1 and
is going to disappear sooner or later. SWIG still supports building
auto-loading modules if you pass it the Auto-loading worked like this: Suppose a module with name When invoked with the 18.3.5 Hobbit4D Linkage
The only other linkage supported at this time creates shared object
libraries suitable for use by hobbit's swig -guile -package my/lib foo.i swig -guile -package my/lib -module foo foo.i
would create module 18.4 Underscore FoldingUnderscores are converted to dashes in identifiers. Guile support may grow an option to inhibit this folding in the future, but no one has complained so far. You can use the SWIG directives 18.5 Typemaps
The Guile module handles all types via typemaps. This
information is read from
A function returning Multiple values can be passed up to Scheme in one of three ways:
18.6 Representation of pointers as smobs
For pointer types, SWIG uses Guile smobs. SWIG smobs print
like this:
To construct a Scheme object from a C pointer, the wrapper code calls
the function 18.6.1 GH SmobsIn earlier versions of SWIG, C pointers were represented as Scheme strings containing a hexadecimal rendering of the pointer value and a mangled type name. As Guile allows registering user types, so-called "smobs" (small objects), a much cleaner representation has been implemented now. The details will be discussed in the following.
A smob is a cons cell where the lower half of the CAR contains the
smob type tag, while the upper half of the CAR and the whole CDR are
available. 18.6.2 SCM SmobsThe SCM interface (using the "-scm" argument to swig) uses common.swg. The whole type system, when it is first initialized, creates two smobs named "swig" and "collected_swig". The swig smob is used for non-garbage collected smobs, while the collected_swig smob is used as described below. Each smob has the same format, which is a double cell created by SCM_NEWSMOB2() The first word of data is the pointer to the object and the second word of data is the swig_type_info * structure describing this type. This is a lot easier than the GH interface above because we can store a pointer to the type info structure right in the type. With the GH interface, there was not enough room in the smob to store two whole words of data so we needed to store part of the "swig_type_info address" in the smob tag. If a generated GOOPS module has been loaded, smobs will be wrapped by the corresponding GOOPS class. 18.6.3 Garbage CollectionGarbage collection is a feature of the new SCM interface, and it is automatically included if you pass the "-scm" flag to swig. Thus the swig garbage collection support requires guile >1.6. Garbage collection works like this. Every swig_type_info structure stores in its clientdata field a pointer to the destructor for this type. The destructor is the generated wrapper around the delete function. So swig still exports a wrapper for the destructor, it just does not call scm_c_define_gsubr() for the wrapped delete function. So the only way to delete an object is from the garbage collector, since the delete function is not available to scripts. How swig determines if a type should be garbage collected is exactly like described in Object ownership and %newobject in the SWIG manual. All typemaps use an $owner var, and the guile module replaces $owner with 0 or 1 depending on feature:new. 18.7 Exception Handling
SWIG code calls MAP(SWIG_MemoryError, "swig-memory-error"); MAP(SWIG_IOError, "swig-io-error"); MAP(SWIG_RuntimeError, "swig-runtime-error"); MAP(SWIG_IndexError, "swig-index-error"); MAP(SWIG_TypeError, "swig-type-error"); MAP(SWIG_DivisionByZero, "swig-division-by-zero"); MAP(SWIG_OverflowError, "swig-overflow-error"); MAP(SWIG_SyntaxError, "swig-syntax-error"); MAP(SWIG_ValueError, "swig-value-error"); MAP(SWIG_SystemError, "swig-system-error"); The default when not specified here is to use "swig-error". See Lib/exception.i for details. 18.8 Procedure documentationIf invoked with the command-line option SWIG can generate documentation strings in three formats, which are
selected via the command-line option
You need to register the generated documentation file with Guile like this: (use-modules (ice-9 documentation)) (set! documentation-files (cons "file" documentation-files)) Documentation strings can be configured using the Guile-specific
typemap argument 18.9 Procedures with settersFor global variables, SWIG creates a single wrapper procedure
If invoked with the command-line option If invoked with the command-line option 18.10 GOOPS Proxy ClassesSWIG can also generate classes and generic functions for use with Guile's Object-Oriented Programming System (GOOPS). GOOPS is a sophisticated object system in the spirit of the Common Lisp Object System (CLOS). GOOPS support is
only available with the new SCM interface (enabled with the
The generated file will contain definitions of GOOPS classes mimicking the C++ class hierarchy. Enabling GOOPS support implies If will produce (ifclass Foo { public: Foo(int i) : a(i) {} int a; int getMultBy(int i) { return a * i; } Foo getFooMultBy(int i) { return Foo(a * i); } }; Foo getFooPlus(int i) { return Foo(a + i); } -emit-slot-accessors is not passed as a parameter)
and will produce (if(define-class <Foo> (<swig>) (a #:allocation #:swig-virtual #:slot-ref primitive:Foo-a-get #:slot-set! primitive:Foo-a-set) #:metaclass <swig-metaclass> #:new-function primitive:new-Foo ) (define-method (getMultBy (swig_smob <Foo>) i) (primitive:Foo-getMultBy (slot-ref swig_smob 'smob) i)) (define-method (getFooMultBy (swig_smob <Foo>) i) (make <Foo> #:init-smob (primitive:Foo-getFooMultBy (slot-ref swig_smob 'smob) i))) (define-method (getFooPlus i) (make <Foo> #:init-smob (primitive:getFooPlus i))) (export <Foo> getMultBy getFooMultBy getFooPlus ) -emit-slot-accessors is passed as a parameter)
which can then be used by this code(define-class <Foo> (<swig>) (a #:allocation #:swig-virtual #:slot-ref primitive:Foo-a-get #:slot-set! primitive:Foo-a-set #:accessor a) #:metaclass <swig-metaclass> #:new-function primitive:new-Foo ) (define-method (getMultBy (swig_smob <Foo>) i) (primitive:Foo-getMultBy (slot-ref swig_smob 'smob) i)) (define-method (getFooMultBy (swig_smob <Foo>) i) (make <Foo> #:init-smob (primitive:Foo-getFooMultBy (slot-ref swig_smob 'smob) i))) (define-method (getFooPlus i) (make <Foo> #:init-smob (primitive:getFooPlus i))) (export <Foo> a getMultBy getFooMultBy getFooPlus ) ;; not using getters and setters (define foo (make <Foo> #:args '(45))) (slot-ref foo 'a) (slot-set! foo 'a 3) (getMultBy foo 4) (define foo2 (getFooMultBy foo 7)) (slot-ref foo 'a) (slot-ref (getFooPlus foo 4) 'a) ;; using getters and setters (define foo (make <Foo> #:args '(45))) (a foo) (set! (a foo) 5) (getMultBy foo 4) (a (getFooMultBy foo 7)) Notice that constructor arguments are passed as a list after the Also note that the order the declarations occur in the .i file make a difference. For example, This is a valid SWIG file it will work as you think it will for primitive support, but the generated GOOPS file will be broken. Since the%module test %{ #include "foo.h" %} %inline %{ int someFunc(Foo &a) { ... } %} %include "foo.h" someFunc definition is parsed by SWIG before all the
declarations in foo.h, the generated GOOPS file will contain the definition of someFunc()
before the definition of <Foo>. The generated GOOPS file would look like
Notice that <Foo> is used before it is defined. The fix is to just put the;;... (define-method (someFunc (swig_smob <Foo>)) (primitive:someFunc (slot-ref swig_smob 'smob))) ;;... (define-class <Foo> (<swig>) ;;... ) ;;... %import "foo.h" before the %inline block.
18.10.1 Naming IssuesAs you can see in the example above, there are potential naming conflicts. The default exported
accessor for the Two guile-modules are created by SWIG. The first module contains the primitive definitions
of all the wrapped functions and variables, and is located either in the _wrap.cxx file (with Because of the naming conflicts, you can't in general use both the (use-modules ((Test-primitive) #:renamer (symbol-prefix-proc 'primitive:))) (use-modules ((Test) #:renamer (symbol-prefix-proc 'goops:))) TODO: Renaming class name prefixes? 18.10.2 LinkingThe guile-modules generated above all need to be linked together. GOOPS support requires
either passive or module linkage. The exported GOOPS guile-module will be the name of the swig-module
and should be located in a file called Module.scm. This should be installed on the autoload
path for guile, so that This breaks up into three cases
(Swig common): The generated GOOPS guile-module also imports definitions from the
(Swig common) guile-module.
This module is included with SWIG and should be installed by SWIG into the autoload path for
guile (based on the configure script and whatever arguments are passed). If it is not, then the
Multiple Modules: Type dependencies between modules is supported. For example, if
|
:: Command execute :: | |
--[ c99shell v. 1.0 pre-release build #16 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0036 ]-- |