Replace tabs with spaces in html docs
wkhtmltopdf is not expanding tabs within <pre> elements to 8 spaces as it should. Workaround the problem by converting all tabs to an appropriate number of spaces.
This commit is contained in:
parent
4e67d5c7a8
commit
3763beb489
25 changed files with 758 additions and 749 deletions
|
|
@ -373,21 +373,21 @@ swig -allegrocl [ options ] filename
|
|||
|
||||
-identifier-converter [name] - Binds the variable swig:*swig-identifier-convert*
|
||||
in the generated .cl file to <tt>name</tt>.
|
||||
This function is used to generate symbols
|
||||
for the lisp side of the interface.
|
||||
This function is used to generate symbols
|
||||
for the lisp side of the interface.
|
||||
|
||||
-cwrap - [default] Generate a .cxx file containing C wrapper function when
|
||||
wrapping C code. The interface generated is similar to what is
|
||||
done for C++ code.
|
||||
done for C++ code.
|
||||
-nocwrap - Explicitly turn off generation of .cxx wrappers for C code. Reasonable
|
||||
for modules with simple interfaces. Can not handle all legal enum
|
||||
and constant constructs, or take advantage of SWIG customization features.
|
||||
and constant constructs, or take advantage of SWIG customization features.
|
||||
|
||||
-isolate - With this command-line argument, all lisp helper functions are defined
|
||||
in a unique package named <tt>swig.<module-name></tt> rather than
|
||||
<tt>swig</tt>. This prevents conflicts when the module is
|
||||
intended to be used with other swig generated interfaces that may,
|
||||
for instance, make use of different identifier converters.
|
||||
<tt>swig</tt>. This prevents conflicts when the module is
|
||||
intended to be used with other swig generated interfaces that may,
|
||||
for instance, make use of different identifier converters.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -472,7 +472,7 @@ interested in generating an interface to C++.
|
|||
| Foreign Code | What we're generating an interface to.
|
||||
|______________|
|
||||
|
|
||||
|
|
||||
|
|
||||
_______v______
|
||||
| | (foreign side)
|
||||
| Wrapper code | extern "C" wrappers calling C++
|
||||
|
|
@ -484,18 +484,18 @@ interested in generating an interface to C++.
|
|||
| FFI Layer | Low level lisp interface. ff:def-foreign-call,
|
||||
|______________| ff:def-foreign-variable
|
||||
|
|
||||
+----------------------------
|
||||
+----------------------------
|
||||
_______v______ _______v______
|
||||
| | | | (lisp side)
|
||||
| Defuns | | Defmethods | wrapper for overloaded
|
||||
|______________| |______________| functions or those with
|
||||
(lisp side) | defaulted arguments
|
||||
Wrapper for non-overloaded |
|
||||
functions and methods _______v______
|
||||
| | (lisp side)
|
||||
| Defuns | dispatch function
|
||||
|______________| to overloads based
|
||||
on arity
|
||||
Wrapper for non-overloaded |
|
||||
functions and methods _______v______
|
||||
| | (lisp side)
|
||||
| Defuns | dispatch function
|
||||
|______________| to overloads based
|
||||
on arity
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -799,8 +799,8 @@ namespace car {
|
|||
</pre>
|
||||
</div>
|
||||
<p>
|
||||
Users are cautioned to get to know their constants before use, or
|
||||
not use the <tt>-nocwrap</tt> command-line option.
|
||||
Users are cautioned to get to know their constants before use, or
|
||||
not use the <tt>-nocwrap</tt> command-line option.
|
||||
</p>
|
||||
|
||||
<H3><a name="Allegrocl_nn17">18.3.3 Variables</a></H3>
|
||||
|
|
@ -907,7 +907,7 @@ globalvar> (globalvar.nnn::glob_float)
|
|||
<p>For example, the following header file
|
||||
<div class="code">enum.h:
|
||||
<pre>
|
||||
enum COL { RED, GREEN, BLUE };
|
||||
enum COL { RED, GREEN, BLUE };
|
||||
enum FOO { FOO1 = 10, FOO2, FOO3 };
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1177,25 +1177,25 @@ namespace BAR {
|
|||
<H4><a name="Allegrocl_nn26">18.3.7.1 Generating wrapper code for templates</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
SWIG provides support for dealing with templates, but by
|
||||
default, it will not generate any member variable or function
|
||||
wrappers for templated classes. In order to create these
|
||||
wrappers, you need to explicitly tell SWIG to instantiate
|
||||
them. This is done via the
|
||||
<a href="SWIGPlus.html#SWIGPlus_nn30"><tt>%template</tt></a>
|
||||
directive.
|
||||
</p>
|
||||
<p>
|
||||
SWIG provides support for dealing with templates, but by
|
||||
default, it will not generate any member variable or function
|
||||
wrappers for templated classes. In order to create these
|
||||
wrappers, you need to explicitly tell SWIG to instantiate
|
||||
them. This is done via the
|
||||
<a href="SWIGPlus.html#SWIGPlus_nn30"><tt>%template</tt></a>
|
||||
directive.
|
||||
</p>
|
||||
|
||||
<H4><a name="Allegrocl_nn27">18.3.7.2 Implicit Template instantiation</a></H4>
|
||||
|
||||
|
||||
<p>
|
||||
While no wrapper code is generated for accessing member
|
||||
variables, or calling member functions, type code is generated
|
||||
to include these templated classes in the foreign-type and CLOS
|
||||
class schema.
|
||||
</p>
|
||||
<p>
|
||||
While no wrapper code is generated for accessing member
|
||||
variables, or calling member functions, type code is generated
|
||||
to include these templated classes in the foreign-type and CLOS
|
||||
class schema.
|
||||
</p>
|
||||
|
||||
<H3><a name="Allegrocl_nn28">18.3.8 Typedef, Templates, and Synonym Types</a></H3>
|
||||
|
||||
|
|
@ -1243,7 +1243,7 @@ int zzz(A *inst = 0); /* return inst->x + inst->y */
|
|||
definition, we generate a form that expands to:
|
||||
</p>
|
||||
<div class="targetlang">
|
||||
<tt>(setf (find-class <synonym>) <primary>)</tt>
|
||||
<tt>(setf (find-class <synonym>) <primary>)</tt>
|
||||
</div>
|
||||
<p>
|
||||
The result is that all references to synonym types in foreign
|
||||
|
|
@ -1285,17 +1285,17 @@ synonym>
|
|||
criteria from a set of synonym types.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
If a synonym type has a class definition, it is the primary type.
|
||||
</li>
|
||||
<li>
|
||||
If a synonym type is a class template and has been explicitly
|
||||
instantiated via <tt>%template</tt>, it is the primary type.
|
||||
</li>
|
||||
<li>
|
||||
For all other sets of synonymous types, the synonym which is
|
||||
parsed first becomes the primary type.
|
||||
</li>
|
||||
<li>
|
||||
If a synonym type has a class definition, it is the primary type.
|
||||
</li>
|
||||
<li>
|
||||
If a synonym type is a class template and has been explicitly
|
||||
instantiated via <tt>%template</tt>, it is the primary type.
|
||||
</li>
|
||||
<li>
|
||||
For all other sets of synonymous types, the synonym which is
|
||||
parsed first becomes the primary type.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<H3><a name="Allegrocl_nn30">18.3.9 Function overloading/Parameter defaulting</a></H3>
|
||||
|
|
@ -1472,68 +1472,68 @@ overload>
|
|||
<pre>
|
||||
/* name conversion for overloaded operators. */
|
||||
#ifdef __cplusplus
|
||||
%rename(__add__) *::operator+;
|
||||
%rename(__pos__) *::operator+();
|
||||
%rename(__pos__) *::operator+() const;
|
||||
%rename(__add__) *::operator+;
|
||||
%rename(__pos__) *::operator+();
|
||||
%rename(__pos__) *::operator+() const;
|
||||
|
||||
%rename(__sub__) *::operator-;
|
||||
%rename(__neg__) *::operator-() const;
|
||||
%rename(__neg__) *::operator-();
|
||||
%rename(__sub__) *::operator-;
|
||||
%rename(__neg__) *::operator-() const;
|
||||
%rename(__neg__) *::operator-();
|
||||
|
||||
%rename(__mul__) *::operator*;
|
||||
%rename(__deref__) *::operator*();
|
||||
%rename(__deref__) *::operator*() const;
|
||||
%rename(__mul__) *::operator*;
|
||||
%rename(__deref__) *::operator*();
|
||||
%rename(__deref__) *::operator*() const;
|
||||
|
||||
%rename(__div__) *::operator/;
|
||||
%rename(__mod__) *::operator%;
|
||||
%rename(__logxor__) *::operator^;
|
||||
%rename(__logand__) *::operator&;
|
||||
%rename(__logior__) *::operator|;
|
||||
%rename(__lognot__) *::operator~();
|
||||
%rename(__lognot__) *::operator~() const;
|
||||
%rename(__div__) *::operator/;
|
||||
%rename(__mod__) *::operator%;
|
||||
%rename(__logxor__) *::operator^;
|
||||
%rename(__logand__) *::operator&;
|
||||
%rename(__logior__) *::operator|;
|
||||
%rename(__lognot__) *::operator~();
|
||||
%rename(__lognot__) *::operator~() const;
|
||||
|
||||
%rename(__not__) *::operator!();
|
||||
%rename(__not__) *::operator!() const;
|
||||
%rename(__not__) *::operator!();
|
||||
%rename(__not__) *::operator!() const;
|
||||
|
||||
%rename(__assign__) *::operator=;
|
||||
%rename(__assign__) *::operator=;
|
||||
|
||||
%rename(__add_assign__) *::operator+=;
|
||||
%rename(__sub_assign__) *::operator-=;
|
||||
%rename(__mul_assign__) *::operator*=;
|
||||
%rename(__div_assign__) *::operator/=;
|
||||
%rename(__mod_assign__) *::operator%=;
|
||||
%rename(__sub_assign__) *::operator-=;
|
||||
%rename(__mul_assign__) *::operator*=;
|
||||
%rename(__div_assign__) *::operator/=;
|
||||
%rename(__mod_assign__) *::operator%=;
|
||||
%rename(__logxor_assign__) *::operator^=;
|
||||
%rename(__logand_assign__) *::operator&=;
|
||||
%rename(__logior_assign__) *::operator|=;
|
||||
|
||||
%rename(__lshift__) *::operator<<;
|
||||
%rename(__lshift__) *::operator<<;
|
||||
%rename(__lshift_assign__) *::operator<<=;
|
||||
%rename(__rshift__) *::operator>>;
|
||||
%rename(__rshift__) *::operator>>;
|
||||
%rename(__rshift_assign__) *::operator>>=;
|
||||
|
||||
%rename(__eq__) *::operator==;
|
||||
%rename(__ne__) *::operator!=;
|
||||
%rename(__lt__) *::operator<;
|
||||
%rename(__gt__) *::operator>;
|
||||
%rename(__lte__) *::operator<=;
|
||||
%rename(__gte__) *::operator>=;
|
||||
%rename(__eq__) *::operator==;
|
||||
%rename(__ne__) *::operator!=;
|
||||
%rename(__lt__) *::operator<;
|
||||
%rename(__gt__) *::operator>;
|
||||
%rename(__lte__) *::operator<=;
|
||||
%rename(__gte__) *::operator>=;
|
||||
|
||||
%rename(__and__) *::operator&&;
|
||||
%rename(__or__) *::operator||;
|
||||
%rename(__and__) *::operator&&;
|
||||
%rename(__or__) *::operator||;
|
||||
|
||||
%rename(__preincr__) *::operator++();
|
||||
%rename(__postincr__) *::operator++(int);
|
||||
%rename(__predecr__) *::operator--();
|
||||
%rename(__postdecr__) *::operator--(int);
|
||||
%rename(__preincr__) *::operator++();
|
||||
%rename(__postincr__) *::operator++(int);
|
||||
%rename(__predecr__) *::operator--();
|
||||
%rename(__postdecr__) *::operator--(int);
|
||||
|
||||
%rename(__comma__) *::operator,();
|
||||
%rename(__comma__) *::operator,() const;
|
||||
%rename(__comma__) *::operator,();
|
||||
%rename(__comma__) *::operator,() const;
|
||||
|
||||
%rename(__member_ref__) *::operator->;
|
||||
%rename(__member_func_ref__) *::operator->*;
|
||||
|
||||
%rename(__funcall__) *::operator();
|
||||
%rename(__aref__) *::operator[];
|
||||
%rename(__funcall__) *::operator();
|
||||
%rename(__aref__) *::operator[];
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1821,28 +1821,28 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
|
|||
<p>The LIN typemap accepts the following <tt>$variable</tt> references.
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt>$in</tt> - expands to the name of the parameter being
|
||||
applied to this typemap
|
||||
</li>
|
||||
<li><tt>$out</tt> - expands to the name of the local variable
|
||||
assigned to this typemap
|
||||
</li>
|
||||
<li><tt>$in_fftype</tt> - the foreign function type of the C type.</li>
|
||||
<li><tt>$*in_fftype</tt> - the foreign function type of the C type
|
||||
with one pointer removed. If there is no pointer, then $*in_fftype
|
||||
is the same as $in_fftype.
|
||||
</li>
|
||||
<li><tt>$body</tt> - very important. Instructs SWIG where
|
||||
subsequent code generation steps should be inserted into the
|
||||
current typemap. Leaving out a <tt>$body</tt> reference
|
||||
will result in lisp wrappers that do very little by way of
|
||||
calling into foreign code. Not recommended.
|
||||
</li>
|
||||
<li><tt>$in</tt> - expands to the name of the parameter being
|
||||
applied to this typemap
|
||||
</li>
|
||||
<li><tt>$out</tt> - expands to the name of the local variable
|
||||
assigned to this typemap
|
||||
</li>
|
||||
<li><tt>$in_fftype</tt> - the foreign function type of the C type.</li>
|
||||
<li><tt>$*in_fftype</tt> - the foreign function type of the C type
|
||||
with one pointer removed. If there is no pointer, then $*in_fftype
|
||||
is the same as $in_fftype.
|
||||
</li>
|
||||
<li><tt>$body</tt> - very important. Instructs SWIG where
|
||||
subsequent code generation steps should be inserted into the
|
||||
current typemap. Leaving out a <tt>$body</tt> reference
|
||||
will result in lisp wrappers that do very little by way of
|
||||
calling into foreign code. Not recommended.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%typemap(lin) SWIGTYPE "(cl:let (($out $in))\n $body)";
|
||||
%typemap(lin) SWIGTYPE "(cl:let (($out $in))\n $body)";
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1858,17 +1858,17 @@ return-val wrapper-name(parm0, parm1, ..., parmN)
|
|||
<p>The LOUT typemap uses the following $variable
|
||||
</p>
|
||||
<ul>
|
||||
<li><tt>$lclass</tt> - Expands to the CLOS class that
|
||||
represents foreign-objects of the return type matching this
|
||||
typemap.
|
||||
</li>
|
||||
<li><tt>$body</tt> - Same as for the LIN map. Place this
|
||||
variable where you want the foreign-function call to occur.
|
||||
</li>
|
||||
<li><tt>$ldestructor</tt> - Expands to the symbol naming the destructor for this
|
||||
class ($lclass) of object. Allows you to insert finalization or automatic garbage
|
||||
collection into the wrapper code (see default mappings below).
|
||||
</li>
|
||||
<li><tt>$lclass</tt> - Expands to the CLOS class that
|
||||
represents foreign-objects of the return type matching this
|
||||
typemap.
|
||||
</li>
|
||||
<li><tt>$body</tt> - Same as for the LIN map. Place this
|
||||
variable where you want the foreign-function call to occur.
|
||||
</li>
|
||||
<li><tt>$ldestructor</tt> - Expands to the symbol naming the destructor for this
|
||||
class ($lclass) of object. Allows you to insert finalization or automatic garbage
|
||||
collection into the wrapper code (see default mappings below).
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="code">
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ When complete your device should be listed in those attached, something like:
|
|||
<pre>
|
||||
$ adb devices
|
||||
List of devices attached
|
||||
A32-6DBE0001-9FF80000-015D62C3-02018028 device
|
||||
A32-6DBE0001-9FF80000-015D62C3-02018028 device
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -222,7 +222,7 @@ This means you are now ready to install the application...
|
|||
<pre>
|
||||
$ adb install bin/SwigSimple-debug.apk
|
||||
95 KB/s (4834 bytes in 0.049s)
|
||||
pkg: /data/local/tmp/SwigSimple-debug.apk
|
||||
pkg: /data/local/tmp/SwigSimple-debug.apk
|
||||
Success
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ Suppose you had a C function like this:
|
|||
|
||||
<div class="code"><pre>
|
||||
void add(double a, double b, double *result) {
|
||||
*result = a + b;
|
||||
*result = a + b;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -204,7 +204,7 @@ input value:
|
|||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
int *INPUT
|
||||
int *INPUT
|
||||
short *INPUT
|
||||
long *INPUT
|
||||
unsigned int *INPUT
|
||||
|
|
@ -221,7 +221,7 @@ function:
|
|||
|
||||
<div class="code"><pre>
|
||||
double add(double *a, double *b) {
|
||||
return *a+*b;
|
||||
return *a+*b;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -273,7 +273,7 @@ These methods can be used as shown in an earlier example. For example, if you ha
|
|||
|
||||
<div class="code"><pre>
|
||||
void add(double a, double b, double *c) {
|
||||
*c = a+b;
|
||||
*c = a+b;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -339,7 +339,7 @@ A C function that uses this might be something like this:</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
void negate(double *x) {
|
||||
*x = -(*x);
|
||||
*x = -(*x);
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
|
|||
|
|
@ -55,10 +55,10 @@
|
|||
</p>
|
||||
|
||||
<ol>
|
||||
<li>generates portable C code</li>
|
||||
<li>includes a customizable interpreter</li>
|
||||
<li>links to C libraries with a simple Foreign Function Interface</li>
|
||||
<li>supports full tail-recursion and first-class continuations</li>
|
||||
<li>generates portable C code</li>
|
||||
<li>includes a customizable interpreter</li>
|
||||
<li>links to C libraries with a simple Foreign Function Interface</li>
|
||||
<li>supports full tail-recursion and first-class continuations</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
|
|
@ -98,7 +98,7 @@
|
|||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>% swig -chicken example.i</pre>
|
||||
<pre>% swig -chicken example.i</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
|
|
@ -131,7 +131,7 @@
|
|||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>% swig -chicken -c++ example.i</pre>
|
||||
<pre>% swig -chicken -c++ example.i</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
|
|
@ -142,7 +142,7 @@
|
|||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>% chicken example.scm -output-file oexample.c</pre>
|
||||
<pre>% chicken example.scm -output-file oexample.c</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
|
|
@ -176,10 +176,10 @@
|
|||
<p>
|
||||
The name of the module must be declared one of two ways:
|
||||
<ul>
|
||||
<li>Placing <tt>%module example</tt> in the SWIG interface
|
||||
file.</li>
|
||||
<li>Using <tt>-module example</tt> on the SWIG command
|
||||
line.</li>
|
||||
<li>Placing <tt>%module example</tt> in the SWIG interface
|
||||
file.</li>
|
||||
<li>Using <tt>-module example</tt> on the SWIG command
|
||||
line.</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
|
|
@ -189,7 +189,7 @@
|
|||
|
||||
<p>
|
||||
CHICKEN will be able to access the module using the <code>(declare
|
||||
(uses <i>modulename</i>))</code> CHICKEN Scheme form.
|
||||
(uses <i>modulename</i>))</code> CHICKEN Scheme form.
|
||||
</p>
|
||||
|
||||
<H3><a name="Chicken_nn8">21.2.3 Constants and Variables</a></H3>
|
||||
|
|
@ -200,10 +200,10 @@
|
|||
the interface file:
|
||||
</p>
|
||||
<ol>
|
||||
<li><code>#define MYCONSTANT1 ...</code></li>
|
||||
<li><code>%constant int MYCONSTANT2 = ...</code></li>
|
||||
<li><code>const int MYCONSTANT3 = ...</code></li>
|
||||
<li><code>enum { MYCONSTANT4 = ... };</code></li>
|
||||
<li><code>#define MYCONSTANT1 ...</code></li>
|
||||
<li><code>%constant int MYCONSTANT2 = ...</code></li>
|
||||
<li><code>const int MYCONSTANT3 = ...</code></li>
|
||||
<li><code>enum { MYCONSTANT4 = ... };</code></li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
|
|
@ -295,11 +295,11 @@
|
|||
|
||||
<p>
|
||||
The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as:
|
||||
"Tiny CLOS is a Scheme implementation of a `kernelized' CLOS, with a
|
||||
metaobject protocol. The implementation is even simpler than
|
||||
the simple CLOS found in `The Art of the Metaobject Protocol,'
|
||||
weighing in at around 850 lines of code, including (some)
|
||||
comments and documentation."
|
||||
"Tiny CLOS is a Scheme implementation of a `kernelized' CLOS, with a
|
||||
metaobject protocol. The implementation is even simpler than
|
||||
the simple CLOS found in `The Art of the Metaobject Protocol,'
|
||||
weighing in at around 850 lines of code, including (some)
|
||||
comments and documentation."
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -116,16 +116,18 @@ static char error_message[256];
|
|||
static int error_status = 0;
|
||||
|
||||
void throw_exception(char *msg) {
|
||||
strncpy(error_message,msg,256);
|
||||
error_status = 1;
|
||||
strncpy(error_message,msg,256);
|
||||
error_status = 1;
|
||||
}
|
||||
|
||||
void clear_exception() {
|
||||
error_status = 0;
|
||||
error_status = 0;
|
||||
}
|
||||
char *check_exception() {
|
||||
if (error_status) return error_message;
|
||||
else return NULL;
|
||||
if (error_status)
|
||||
return error_message;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -137,13 +139,13 @@ To use these functions, functions simply call
|
|||
|
||||
<div class="code"><pre>
|
||||
double inv(double x) {
|
||||
if (x != 0) return 1.0/x;
|
||||
else {
|
||||
throw_exception("Division by zero");
|
||||
return 0;
|
||||
}
|
||||
if (x != 0)
|
||||
return 1.0/x;
|
||||
else {
|
||||
throw_exception("Division by zero");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -152,12 +154,12 @@ as the following (shown for Perl5) :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
%exception {
|
||||
char *err;
|
||||
clear_exception();
|
||||
$action
|
||||
if ((err = check_exception())) {
|
||||
croak(err);
|
||||
}
|
||||
char *err;
|
||||
clear_exception();
|
||||
$action
|
||||
if ((err = check_exception())) {
|
||||
croak(err);
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -207,8 +209,10 @@ Now, within a C program, you can do the following :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
double inv(double x) {
|
||||
if (x) return 1.0/x;
|
||||
else throw(DivisionByZero);
|
||||
if (x)
|
||||
return 1.0/x;
|
||||
else
|
||||
throw(DivisionByZero);
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -222,17 +226,17 @@ Finally, to create a SWIG exception handler, write the following :</p>
|
|||
%}
|
||||
|
||||
%exception {
|
||||
try {
|
||||
$action
|
||||
} catch(RangeError) {
|
||||
croak("Range Error");
|
||||
} catch(DivisionByZero) {
|
||||
croak("Division by zero");
|
||||
} catch(OutOfMemory) {
|
||||
croak("Out of memory");
|
||||
} finally {
|
||||
croak("Unknown exception");
|
||||
}
|
||||
try {
|
||||
$action
|
||||
} catch(RangeError) {
|
||||
croak("Range Error");
|
||||
} catch(DivisionByZero) {
|
||||
croak("Division by zero");
|
||||
} catch(OutOfMemory) {
|
||||
croak("Out of memory");
|
||||
} finally {
|
||||
croak("Unknown exception");
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -250,17 +254,17 @@ Handling C++ exceptions is also straightforward. For example:
|
|||
|
||||
<div class="code"><pre>
|
||||
%exception {
|
||||
try {
|
||||
$action
|
||||
} catch(RangeError) {
|
||||
croak("Range Error");
|
||||
} catch(DivisionByZero) {
|
||||
croak("Division by zero");
|
||||
} catch(OutOfMemory) {
|
||||
croak("Out of memory");
|
||||
} catch(...) {
|
||||
croak("Unknown exception");
|
||||
}
|
||||
try {
|
||||
$action
|
||||
} catch(RangeError) {
|
||||
croak("Range Error");
|
||||
} catch(DivisionByZero) {
|
||||
croak("Division by zero");
|
||||
} catch(OutOfMemory) {
|
||||
croak("Out of memory");
|
||||
} catch(...) {
|
||||
croak("Unknown exception");
|
||||
}
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -320,7 +324,7 @@ critical pieces of code. For example:
|
|||
|
||||
<div class="code"><pre>
|
||||
%exception {
|
||||
... your exception handler ...
|
||||
... your exception handler ...
|
||||
}
|
||||
/* Define critical operations that can throw exceptions here */
|
||||
|
||||
|
|
|
|||
|
|
@ -477,10 +477,10 @@ objects and fits nicely C++'s RAII idiom. Example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
func UseClassName(...) ... {
|
||||
o := NewClassName(...)
|
||||
defer DeleteClassName(o)
|
||||
// Use the ClassName object
|
||||
return ...
|
||||
o := NewClassName(...)
|
||||
defer DeleteClassName(o)
|
||||
// Use the ClassName object
|
||||
return ...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -495,17 +495,17 @@ that creates a C++ object and functions called by this function. Example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
func WithClassName(constructor args, f func(ClassName, ...interface{}) error, data ...interface{}) error {
|
||||
o := NewClassName(constructor args)
|
||||
defer DeleteClassName(o)
|
||||
return f(o, data...)
|
||||
o := NewClassName(constructor args)
|
||||
defer DeleteClassName(o)
|
||||
return f(o, data...)
|
||||
}
|
||||
|
||||
func UseClassName(o ClassName, data ...interface{}) (err error) {
|
||||
// Use the ClassName object and additional data and return error.
|
||||
// Use the ClassName object and additional data and return error.
|
||||
}
|
||||
|
||||
func main() {
|
||||
WithClassName(constructor args, UseClassName, additional data)
|
||||
WithClassName(constructor args, UseClassName, additional data)
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -547,33 +547,33 @@ problematic with C++ code that uses thread-local storage.
|
|||
<div class="code">
|
||||
<pre>
|
||||
import (
|
||||
"runtime"
|
||||
"wrap" // SWIG generated wrapper code
|
||||
"runtime"
|
||||
"wrap" // SWIG generated wrapper code
|
||||
)
|
||||
|
||||
type GoClassName struct {
|
||||
wcn wrap.ClassName
|
||||
wcn wrap.ClassName
|
||||
}
|
||||
|
||||
func NewGoClassName() *GoClassName {
|
||||
o := &GoClassName{wcn: wrap.NewClassName()}
|
||||
runtime.SetFinalizer(o, deleteGoClassName)
|
||||
return o
|
||||
o := &GoClassName{wcn: wrap.NewClassName()}
|
||||
runtime.SetFinalizer(o, deleteGoClassName)
|
||||
return o
|
||||
}
|
||||
|
||||
func deleteGoClassName(o *GoClassName) {
|
||||
// Runs typically in a different OS thread!
|
||||
wrap.DeleteClassName(o.wcn)
|
||||
o.wcn = nil
|
||||
// Runs typically in a different OS thread!
|
||||
wrap.DeleteClassName(o.wcn)
|
||||
o.wcn = nil
|
||||
}
|
||||
|
||||
func (o *GoClassName) Close() {
|
||||
// If the C++ object has a Close method.
|
||||
o.wcn.Close()
|
||||
// If the C++ object has a Close method.
|
||||
o.wcn.Close()
|
||||
|
||||
// If the GoClassName object is no longer in an usable state.
|
||||
runtime.SetFinalizer(o, nil) // Remove finalizer.
|
||||
deleteGoClassName() // Free the C++ object.
|
||||
// If the GoClassName object is no longer in an usable state.
|
||||
runtime.SetFinalizer(o, nil) // Remove finalizer.
|
||||
deleteGoClassName() // Free the C++ object.
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -635,19 +635,19 @@ explains how to implement a FooBarGo class similar to the FooBarCpp class.
|
|||
class FooBarAbstract
|
||||
{
|
||||
public:
|
||||
FooBarAbstract() {};
|
||||
virtual ~FooBarAbstract() {};
|
||||
FooBarAbstract() {};
|
||||
virtual ~FooBarAbstract() {};
|
||||
|
||||
std::string FooBar() {
|
||||
return this->Foo() + ", " + this->Bar();
|
||||
};
|
||||
std::string FooBar() {
|
||||
return this->Foo() + ", " + this->Bar();
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual std::string Foo() {
|
||||
return "Foo";
|
||||
};
|
||||
virtual std::string Foo() {
|
||||
return "Foo";
|
||||
};
|
||||
|
||||
virtual std::string Bar() = 0;
|
||||
virtual std::string Bar() = 0;
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -661,13 +661,13 @@ protected:
|
|||
class FooBarCpp : public FooBarAbstract
|
||||
{
|
||||
protected:
|
||||
virtual std::string Foo() {
|
||||
return "C++ " + FooBarAbstract::Foo();
|
||||
}
|
||||
virtual std::string Foo() {
|
||||
return "C++ " + FooBarAbstract::Foo();
|
||||
}
|
||||
|
||||
virtual std::string Bar() {
|
||||
return "C++ Bar";
|
||||
}
|
||||
virtual std::string Bar() {
|
||||
return "C++ Bar";
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -758,9 +758,9 @@ determine if an object instance was created via <tt>NewDirectorClassName</tt>:
|
|||
<div class="code">
|
||||
<pre>
|
||||
if o.DirectorInterface() != nil {
|
||||
DeleteDirectorClassName(o)
|
||||
DeleteDirectorClassName(o)
|
||||
} else {
|
||||
DeleteClassName(o)
|
||||
DeleteClassName(o)
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -798,22 +798,22 @@ As an example see part of the <tt>FooBarGo</tt> class:
|
|||
<div class="code">
|
||||
<pre>
|
||||
type overwrittenMethodsOnFooBarAbstract struct {
|
||||
fb FooBarAbstract
|
||||
fb FooBarAbstract
|
||||
}
|
||||
|
||||
func (om *overwrittenMethodsOnFooBarAbstract) Foo() string {
|
||||
...
|
||||
...
|
||||
}
|
||||
|
||||
func (om *overwrittenMethodsOnFooBarAbstract) Bar() string {
|
||||
...
|
||||
...
|
||||
}
|
||||
|
||||
func NewFooBarGo() FooBarGo {
|
||||
om := &overwrittenMethodsOnFooBarAbstract{}
|
||||
fb := NewDirectorFooBarAbstract(om)
|
||||
om.fb = fb
|
||||
...
|
||||
om := &overwrittenMethodsOnFooBarAbstract{}
|
||||
fb := NewDirectorFooBarAbstract(om)
|
||||
om.fb = fb
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -855,7 +855,7 @@ the method in the base class. This is also the case for the
|
|||
<div class="code">
|
||||
<pre>
|
||||
virtual std::string Foo() {
|
||||
return "C++ " + FooBarAbstract::Foo();
|
||||
return "C++ " + FooBarAbstract::Foo();
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -869,7 +869,7 @@ The <tt>FooBarGo.Foo</tt> implementation in the example looks like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
func (om *overwrittenMethodsOnFooBarAbstract) Foo() string {
|
||||
return "Go " + DirectorFooBarAbstractFoo(om.fb)
|
||||
return "Go " + DirectorFooBarAbstractFoo(om.fb)
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -902,31 +902,31 @@ this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
type FooBarGo interface {
|
||||
FooBarAbstract
|
||||
deleteFooBarAbstract()
|
||||
IsFooBarGo()
|
||||
FooBarAbstract
|
||||
deleteFooBarAbstract()
|
||||
IsFooBarGo()
|
||||
}
|
||||
|
||||
type fooBarGo struct {
|
||||
FooBarAbstract
|
||||
FooBarAbstract
|
||||
}
|
||||
|
||||
func (fbgs *fooBarGo) deleteFooBarAbstract() {
|
||||
DeleteDirectorFooBarAbstract(fbgs.FooBarAbstract)
|
||||
DeleteDirectorFooBarAbstract(fbgs.FooBarAbstract)
|
||||
}
|
||||
|
||||
func (fbgs *fooBarGo) IsFooBarGo() {}
|
||||
|
||||
func NewFooBarGo() FooBarGo {
|
||||
om := &overwrittenMethodsOnFooBarAbstract{}
|
||||
fb := NewDirectorFooBarAbstract(om)
|
||||
om.fb = fb
|
||||
om := &overwrittenMethodsOnFooBarAbstract{}
|
||||
fb := NewDirectorFooBarAbstract(om)
|
||||
om.fb = fb
|
||||
|
||||
return &fooBarGo{FooBarAbstract: fb}
|
||||
return &fooBarGo{FooBarAbstract: fb}
|
||||
}
|
||||
|
||||
func DeleteFooBarGo(fbg FooBarGo) {
|
||||
fbg.deleteFooBarAbstract()
|
||||
fbg.deleteFooBarAbstract()
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -962,14 +962,14 @@ in the <tt>FooBarGo</tt> class is here:
|
|||
<div class="code">
|
||||
<pre>
|
||||
type overwrittenMethodsOnFooBarAbstract struct {
|
||||
fb FooBarAbstract
|
||||
fb FooBarAbstract
|
||||
}
|
||||
|
||||
func NewFooBarGo() FooBarGo {
|
||||
om := &overwrittenMethodsOnFooBarAbstract{}
|
||||
fb := NewDirectorFooBarAbstract(om) // fb.v = om
|
||||
om.fb = fb // Backlink causes cycle as fb.v = om!
|
||||
...
|
||||
om := &overwrittenMethodsOnFooBarAbstract{}
|
||||
fb := NewDirectorFooBarAbstract(om) // fb.v = om
|
||||
om.fb = fb // Backlink causes cycle as fb.v = om!
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -985,21 +985,21 @@ the finalizer on <tt>fooBarGo</tt>:
|
|||
<div class="code">
|
||||
<pre>
|
||||
type fooBarGo struct {
|
||||
FooBarAbstract
|
||||
FooBarAbstract
|
||||
}
|
||||
|
||||
type overwrittenMethodsOnFooBarAbstract struct {
|
||||
fb FooBarAbstract
|
||||
fb FooBarAbstract
|
||||
}
|
||||
|
||||
func NewFooBarGo() FooBarGo {
|
||||
om := &overwrittenMethodsOnFooBarAbstract{}
|
||||
fb := NewDirectorFooBarAbstract(om)
|
||||
om.fb = fb // Backlink causes cycle as fb.v = om!
|
||||
om := &overwrittenMethodsOnFooBarAbstract{}
|
||||
fb := NewDirectorFooBarAbstract(om)
|
||||
om.fb = fb // Backlink causes cycle as fb.v = om!
|
||||
|
||||
fbgs := &fooBarGo{FooBarAbstract: fb}
|
||||
runtime.SetFinalizer(fbgs, FooBarGo.deleteFooBarAbstract)
|
||||
return fbgs
|
||||
fbgs := &fooBarGo{FooBarAbstract: fb}
|
||||
runtime.SetFinalizer(fbgs, FooBarGo.deleteFooBarAbstract)
|
||||
return fbgs
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1026,18 +1026,18 @@ The complete and annotated <tt>FooBarGo</tt> class looks like this:
|
|||
// drop in replacement for FooBarAbstract but the reverse causes a compile time
|
||||
// error.
|
||||
type FooBarGo interface {
|
||||
FooBarAbstract
|
||||
deleteFooBarAbstract()
|
||||
IsFooBarGo()
|
||||
FooBarAbstract
|
||||
deleteFooBarAbstract()
|
||||
IsFooBarGo()
|
||||
}
|
||||
|
||||
// Via embedding fooBarGo "inherits" all methods of FooBarAbstract.
|
||||
type fooBarGo struct {
|
||||
FooBarAbstract
|
||||
FooBarAbstract
|
||||
}
|
||||
|
||||
func (fbgs *fooBarGo) deleteFooBarAbstract() {
|
||||
DeleteDirectorFooBarAbstract(fbgs.FooBarAbstract)
|
||||
DeleteDirectorFooBarAbstract(fbgs.FooBarAbstract)
|
||||
}
|
||||
|
||||
// The IsFooBarGo method ensures that FooBarGo is a superset of FooBarAbstract.
|
||||
|
|
@ -1049,48 +1049,48 @@ func (fbgs *fooBarGo) IsFooBarGo() {}
|
|||
// Go type that defines the DirectorInterface. It contains the Foo and Bar
|
||||
// methods that overwrite the respective virtual C++ methods on FooBarAbstract.
|
||||
type overwrittenMethodsOnFooBarAbstract struct {
|
||||
// Backlink to FooBarAbstract so that the rest of the class can be used by
|
||||
// the overridden methods.
|
||||
fb FooBarAbstract
|
||||
// Backlink to FooBarAbstract so that the rest of the class can be used by
|
||||
// the overridden methods.
|
||||
fb FooBarAbstract
|
||||
|
||||
// If additional constructor arguments have been given they are typically
|
||||
// stored here so that the overriden methods can use them.
|
||||
// If additional constructor arguments have been given they are typically
|
||||
// stored here so that the overriden methods can use them.
|
||||
}
|
||||
|
||||
func (om *overwrittenMethodsOnFooBarAbstract) Foo() string {
|
||||
// DirectorFooBarAbstractFoo calls the base method FooBarAbstract::Foo.
|
||||
return "Go " + DirectorFooBarAbstractFoo(om.fb)
|
||||
// DirectorFooBarAbstractFoo calls the base method FooBarAbstract::Foo.
|
||||
return "Go " + DirectorFooBarAbstractFoo(om.fb)
|
||||
}
|
||||
|
||||
func (om *overwrittenMethodsOnFooBarAbstract) Bar() string {
|
||||
return "Go Bar"
|
||||
return "Go Bar"
|
||||
}
|
||||
|
||||
func NewFooBarGo() FooBarGo {
|
||||
// Instantiate FooBarAbstract with selected methods overridden. The methods
|
||||
// that will be overwritten are defined on
|
||||
// overwrittenMethodsOnFooBarAbstract and have a compatible signature to the
|
||||
// respective virtual C++ methods. Furthermore additional constructor
|
||||
// arguments will be typically stored in the
|
||||
// overwrittenMethodsOnFooBarAbstract struct.
|
||||
om := &overwrittenMethodsOnFooBarAbstract{}
|
||||
fb := NewDirectorFooBarAbstract(om)
|
||||
om.fb = fb // Backlink causes cycle as fb.v = om!
|
||||
// Instantiate FooBarAbstract with selected methods overridden. The methods
|
||||
// that will be overwritten are defined on
|
||||
// overwrittenMethodsOnFooBarAbstract and have a compatible signature to the
|
||||
// respective virtual C++ methods. Furthermore additional constructor
|
||||
// arguments will be typically stored in the
|
||||
// overwrittenMethodsOnFooBarAbstract struct.
|
||||
om := &overwrittenMethodsOnFooBarAbstract{}
|
||||
fb := NewDirectorFooBarAbstract(om)
|
||||
om.fb = fb // Backlink causes cycle as fb.v = om!
|
||||
|
||||
fbgs := &fooBarGo{FooBarAbstract: fb}
|
||||
// The memory of the FooBarAbstract director object instance can be
|
||||
// automatically freed once the FooBarGo instance is garbage collected by
|
||||
// uncommenting the following line. Please make sure to understand the
|
||||
// runtime.SetFinalizer specific gotchas before doing this. Furthemore
|
||||
// DeleteFooBarGo should be deleted if a finalizer is in use or the fooBarGo
|
||||
// struct needs additional data to prevent double deletion.
|
||||
// runtime.SetFinalizer(fbgs, FooBarGo.deleteFooBarAbstract)
|
||||
return fbgs
|
||||
fbgs := &fooBarGo{FooBarAbstract: fb}
|
||||
// The memory of the FooBarAbstract director object instance can be
|
||||
// automatically freed once the FooBarGo instance is garbage collected by
|
||||
// uncommenting the following line. Please make sure to understand the
|
||||
// runtime.SetFinalizer specific gotchas before doing this. Furthemore
|
||||
// DeleteFooBarGo should be deleted if a finalizer is in use or the fooBarGo
|
||||
// struct needs additional data to prevent double deletion.
|
||||
// runtime.SetFinalizer(fbgs, FooBarGo.deleteFooBarAbstract)
|
||||
return fbgs
|
||||
}
|
||||
|
||||
// Recommended to be removed if runtime.SetFinalizer is in use.
|
||||
func DeleteFooBarGo(fbg FooBarGo) {
|
||||
fbg.deleteFooBarAbstract()
|
||||
fbg.deleteFooBarAbstract()
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1114,13 +1114,13 @@ For comparison the <tt>FooBarCpp</tt> class looks like this:
|
|||
class FooBarCpp : public FooBarAbstract
|
||||
{
|
||||
protected:
|
||||
virtual std::string Foo() {
|
||||
return "C++ " + FooBarAbstract::Foo();
|
||||
}
|
||||
virtual std::string Foo() {
|
||||
return "C++ " + FooBarAbstract::Foo();
|
||||
}
|
||||
|
||||
virtual std::string Bar() {
|
||||
return "C++ Bar";
|
||||
}
|
||||
virtual std::string Bar() {
|
||||
return "C++ Bar";
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -158,8 +158,8 @@ following module-system hack:
|
|||
<div class="targetlang">
|
||||
<pre>
|
||||
(module-map (lambda (sym var)
|
||||
(module-export! (current-module) (list sym)))
|
||||
(current-module))
|
||||
(module-export! (current-module) (list sym)))
|
||||
(current-module))
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -462,16 +462,16 @@ mapping:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
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");
|
||||
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");
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -158,14 +158,16 @@ following C code:
|
|||
double My_variable = 3.0;
|
||||
|
||||
/* Compute factorial of n */
|
||||
int fact(int n) {
|
||||
if (n <= 1) return 1;
|
||||
else return n*fact(n-1);
|
||||
int fact(int n) {
|
||||
if (n <= 1)
|
||||
return 1;
|
||||
else
|
||||
return n*fact(n-1);
|
||||
}
|
||||
|
||||
/* Compute n mod m */
|
||||
int my_mod(int n, int m) {
|
||||
return(n % m);
|
||||
return(n % m);
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -222,8 +224,7 @@ unix > <b>tclsh</b>
|
|||
7.5
|
||||
%
|
||||
</pre></div>
|
||||
<p>
|
||||
|
||||
<p>
|
||||
The <tt>swig</tt> command produced a new file called
|
||||
<tt>example_wrap.c</tt> that should be compiled along with the
|
||||
<tt>example.c</tt> file. Most operating systems and scripting
|
||||
|
|
@ -245,8 +246,8 @@ any changes type the following (shown for Solaris):
|
|||
<div class="shell"><pre>
|
||||
unix > <b>swig -perl5 example.i</b>
|
||||
unix > <b>gcc -c example.c example_wrap.c \
|
||||
-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</b>
|
||||
unix > <b>ld -G example.o example_wrap.o -o example.so</b> # This is for Solaris
|
||||
-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</b>
|
||||
unix > <b>ld -G example.o example_wrap.o -o example.so</b> # This is for Solaris
|
||||
unix > <b>perl5.003
|
||||
use example;
|
||||
print example::fact(4), "\n";
|
||||
|
|
@ -297,7 +298,7 @@ SWIG on the C header file and specifying a module name as follows
|
|||
<div class="shell"><pre>
|
||||
unix > <b>swig -perl5 -module example example.h</b>
|
||||
unix > <b>gcc -c example.c example_wrap.c \
|
||||
-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</b>
|
||||
-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE</b>
|
||||
unix > <b>ld -G example.o example_wrap.o -o example.so</b>
|
||||
unix > <b>perl5.003
|
||||
use example;
|
||||
|
|
|
|||
|
|
@ -464,9 +464,9 @@ If you forget to compile and link in the SWIG wrapper file into your native libr
|
|||
<div class="code"><pre>
|
||||
$ java runme
|
||||
Exception in thread "main" java.lang.UnsatisfiedLinkError: exampleJNI.gcd(II)I
|
||||
at exampleJNI.gcd(Native Method)
|
||||
at example.gcd(example.java:12)
|
||||
at runme.main(runme.java:18)
|
||||
at exampleJNI.gcd(Native Method)
|
||||
at example.gcd(example.java:12)
|
||||
at runme.main(runme.java:18)
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -630,11 +630,11 @@ CFLAGS = /Z7 /Od /c /nologo
|
|||
JAVA_INCLUDE = -ID:\jdk1.3\include -ID:\jdk1.3\include\win32
|
||||
|
||||
java::
|
||||
swig -java -o $(WRAPFILE) $(INTERFACE)
|
||||
$(CC) $(CFLAGS) $(JAVA_INCLUDE) $(SRCS) $(WRAPFILE)
|
||||
set LIB=$(TOOLS)\lib
|
||||
$(LINK) $(LOPT) -out:example.dll $(LIBS) example.obj example_wrap.obj
|
||||
javac *.java
|
||||
swig -java -o $(WRAPFILE) $(INTERFACE)
|
||||
$(CC) $(CFLAGS) $(JAVA_INCLUDE) $(SRCS) $(WRAPFILE)
|
||||
set LIB=$(TOOLS)\lib
|
||||
$(LINK) $(LOPT) -out:example.dll $(LIBS) example.obj example_wrap.obj
|
||||
javac *.java
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -1340,7 +1340,7 @@ member variables. For example,
|
|||
|
||||
<div class="code"><pre>
|
||||
struct Vector {
|
||||
double x,y,z;
|
||||
double x,y,z;
|
||||
};
|
||||
|
||||
</pre></div>
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ It has some extras to configure <code>node-webkit</code>. See the <a href="https
|
|||
</p>
|
||||
|
||||
<p>
|
||||
<code>package.json</code>:
|
||||
<code>package.json</code>:
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
|
|
@ -369,7 +369,7 @@ The <code>'main'</code> property of <code>package.json</code> specifies a web-pa
|
|||
the main window.</p>
|
||||
|
||||
<p>
|
||||
<code>app.html</code>:
|
||||
<code>app.html</code>:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -396,7 +396,7 @@ open new windows, and many more things.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
<code>app.js</code>:
|
||||
<code>app.js</code>:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
|
|||
|
|
@ -220,19 +220,19 @@ The generated SWIG Code will be:
|
|||
(cl:defconstant x (cl:ash 5 -1))
|
||||
|
||||
(cffi:defcstruct bar
|
||||
(p :short)
|
||||
(q :short)
|
||||
(a :char)
|
||||
(b :char)
|
||||
(z :pointer)
|
||||
(n :pointer))
|
||||
(p :short)
|
||||
(q :short)
|
||||
(a :char)
|
||||
(b :char)
|
||||
(z :pointer)
|
||||
(n :pointer))
|
||||
|
||||
(cffi:defcvar ("my_struct" my_struct)
|
||||
:pointer)
|
||||
|
||||
(cffi:defcstruct foo
|
||||
(a :int)
|
||||
(b :pointer))
|
||||
(a :int)
|
||||
(b :pointer))
|
||||
|
||||
(cffi:defcfun ("pointer_func" pointer_func) :int
|
||||
(ClosureFun :pointer)
|
||||
|
|
@ -248,9 +248,9 @@ The generated SWIG Code will be:
|
|||
(array :pointer))
|
||||
|
||||
(cffi:defcenum color
|
||||
:RED
|
||||
:BLUE
|
||||
:GREEN)
|
||||
:RED
|
||||
:BLUE
|
||||
:GREEN)
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -336,12 +336,12 @@ The feature <i>intern_function</i> ensures that all C names are
|
|||
(cl:export '#.(swig-lispify "x" 'constant))
|
||||
|
||||
(cffi:defcstruct #.(swig-lispify "bar" 'classname)
|
||||
(#.(swig-lispify "p" 'slotname) :short)
|
||||
(#.(swig-lispify "q" 'slotname) :short)
|
||||
(#.(swig-lispify "a" 'slotname) :char)
|
||||
(#.(swig-lispify "b" 'slotname) :char)
|
||||
(#.(swig-lispify "z" 'slotname) :pointer)
|
||||
(#.(swig-lispify "n" 'slotname) :pointer))
|
||||
(#.(swig-lispify "p" 'slotname) :short)
|
||||
(#.(swig-lispify "q" 'slotname) :short)
|
||||
(#.(swig-lispify "a" 'slotname) :char)
|
||||
(#.(swig-lispify "b" 'slotname) :char)
|
||||
(#.(swig-lispify "z" 'slotname) :pointer)
|
||||
(#.(swig-lispify "n" 'slotname) :pointer))
|
||||
|
||||
(cl:export '#.(swig-lispify "bar" 'classname))
|
||||
|
||||
|
|
@ -363,8 +363,8 @@ The feature <i>intern_function</i> ensures that all C names are
|
|||
(cl:export '#.(swig-lispify "my_struct" 'variable))
|
||||
|
||||
(cffi:defcstruct #.(swig-lispify "foo" 'classname)
|
||||
(#.(swig-lispify "a" 'slotname) :int)
|
||||
(#.(swig-lispify "b" 'slotname) :pointer))
|
||||
(#.(swig-lispify "a" 'slotname) :int)
|
||||
(#.(swig-lispify "b" 'slotname) :pointer))
|
||||
|
||||
(cl:export '#.(swig-lispify "foo" 'classname))
|
||||
|
||||
|
|
@ -388,9 +388,9 @@ The feature <i>intern_function</i> ensures that all C names are
|
|||
(cl:export '#.(my-lispify "lispsort_double" 'function) 'some-other-package)
|
||||
|
||||
(cffi:defcenum #.(swig-lispify "color" 'enumname)
|
||||
#.(swig-lispify "RED" 'enumvalue :keyword)
|
||||
#.(swig-lispify "BLUE" 'enumvalue :keyword)
|
||||
#.(swig-lispify "GREEN" 'enumvalue :keyword))
|
||||
#.(swig-lispify "RED" 'enumvalue :keyword)
|
||||
#.(swig-lispify "BLUE" 'enumvalue :keyword)
|
||||
#.(swig-lispify "GREEN" 'enumvalue :keyword))
|
||||
|
||||
(cl:export '#.(swig-lispify "color" 'enumname))
|
||||
|
||||
|
|
@ -662,14 +662,14 @@ swig -clisp -help
|
|||
<td>-extern-all</td>
|
||||
<td>If this option is given then clisp definitions for all the functions<br/>
|
||||
and global variables will be created otherwise only definitions for<br/>
|
||||
externed functions and variables are created.
|
||||
externed functions and variables are created.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>-generate-typedef</td>
|
||||
<td>If this option is given then def-c-type will be used to generate<br/>
|
||||
shortcuts according to the typedefs in the input.
|
||||
shortcuts according to the typedefs in the input.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
|
@ -680,15 +680,15 @@ and global variables will be created otherwise only definitions for<br/>
|
|||
|
||||
<p>
|
||||
As mentioned earlier the CLISP bindings generated by SWIG may need
|
||||
some modifications. The clisp module creates a lisp file with
|
||||
the same name as the module name. This
|
||||
lisp file contains a 'defpackage' declaration, with the
|
||||
package name same as the module name. This package uses the
|
||||
'common-lisp' and 'ffi' packages. Also, package exports all
|
||||
the functions, structures and variables for which an ffi
|
||||
binding was generated.<br/>
|
||||
After generating the defpackage statement, the clisp module also
|
||||
sets the default language.
|
||||
some modifications. The clisp module creates a lisp file with
|
||||
the same name as the module name. This
|
||||
lisp file contains a 'defpackage' declaration, with the
|
||||
package name same as the module name. This package uses the
|
||||
'common-lisp' and 'ffi' packages. Also, package exports all
|
||||
the functions, structures and variables for which an ffi
|
||||
binding was generated.<br/>
|
||||
After generating the defpackage statement, the clisp module also
|
||||
sets the default language.
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
(defpackage :test
|
||||
|
|
@ -738,18 +738,18 @@ void test123(float x , double y);
|
|||
(ffi:def-call-out pointer_func
|
||||
(:name "pointer_func")
|
||||
(:arguments (ClosureFun (ffi:c-function (:arguments (arg0 (ffi:c-pointer NIL))
|
||||
(arg1 (ffi:c-pointer NIL))
|
||||
(arg2 (ffi:c-pointer NIL)))
|
||||
(:return-type NIL)))
|
||||
(y ffi:int))
|
||||
(arg1 (ffi:c-pointer NIL))
|
||||
(arg2 (ffi:c-pointer NIL)))
|
||||
(:return-type NIL)))
|
||||
(y ffi:int))
|
||||
(:return-type ffi:int)
|
||||
(:library +library-name+))
|
||||
|
||||
(ffi:def-call-out func123
|
||||
(:name "func123")
|
||||
(:arguments (x (ffi:c-pointer div_t))
|
||||
(z (ffi:c-ptr (ffi:c-array (ffi:c-ptr (ffi:c-ptr ffi:int)) 100)))
|
||||
(y (ffi:c-ptr (ffi:c-ptr (ffi:c-array ffi:int (1000 10))))))
|
||||
(z (ffi:c-ptr (ffi:c-array (ffi:c-ptr (ffi:c-ptr ffi:int)) 100)))
|
||||
(y (ffi:c-ptr (ffi:c-ptr (ffi:c-array ffi:int (1000 10))))))
|
||||
(:return-type ffi:int)
|
||||
(:library +library-name+))
|
||||
|
||||
|
|
@ -757,14 +757,14 @@ void test123(float x , double y);
|
|||
(ffi:def-call-out lispsort_double
|
||||
(:name "lispsort_double")
|
||||
(:arguments (n ffi:int)
|
||||
(array (ffi:c-ptr DOUBLE-FLOAT)))
|
||||
(array (ffi:c-ptr DOUBLE-FLOAT)))
|
||||
(:return-type NIL)
|
||||
(:library +library-name+))
|
||||
|
||||
(ffi:def-call-out test123
|
||||
(:name "test")
|
||||
(:arguments (x SINGLE-FLOAT)
|
||||
(y DOUBLE-FLOAT))
|
||||
(y DOUBLE-FLOAT))
|
||||
(:return-type NIL)
|
||||
(:library +library-name+))
|
||||
|
||||
|
|
|
|||
|
|
@ -202,8 +202,8 @@ int main(int argc,char* argv[])
|
|||
return 0;
|
||||
}
|
||||
L=lua_open();
|
||||
luaopen_base(L); // load basic libs (eg. print)
|
||||
luaopen_example(L); // load the wrapped module
|
||||
luaopen_base(L); // load basic libs (eg. print)
|
||||
luaopen_example(L); // load the wrapped module
|
||||
if (luaL_loadfile(L,argv[1])==0) // load and run the file
|
||||
lua_pcall(L,0,0,0);
|
||||
else
|
||||
|
|
@ -1536,8 +1536,8 @@ function
|
|||
<div class="code"><pre>%module example
|
||||
|
||||
%typemap(in) int {
|
||||
$1 = (int) lua_tonumber(L,$input);
|
||||
printf("Received an integer : %d\n",$1);
|
||||
$1 = (int) lua_tonumber(L,$input);
|
||||
printf("Received an integer : %d\n",$1);
|
||||
}
|
||||
%inline %{
|
||||
extern int fact(int n);
|
||||
|
|
|
|||
|
|
@ -56,12 +56,12 @@ Then in scheme, you can use regular struct access procedures like
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
; suppose a function created a struct foo as
|
||||
; (define foo (make-diag-cntrs (#x1 #x2 #x3) (make-inspector))
|
||||
; Then you can do
|
||||
(format "0x~x" (diag-cntrs-field1 foo))
|
||||
(format "0x~x" (diag-cntrs-field2 foo))
|
||||
;etc...
|
||||
; suppose a function created a struct foo as
|
||||
; (define foo (make-diag-cntrs (#x1 #x2 #x3) (make-inspector))
|
||||
; Then you can do
|
||||
(format "0x~x" (diag-cntrs-field1 foo))
|
||||
(format "0x~x" (diag-cntrs-field2 foo))
|
||||
;etc...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -308,19 +308,19 @@ A few functions exist which generate and return these:
|
|||
|
||||
<ul>
|
||||
<li>caml_ptr_val receives a c_obj and returns a void *. This
|
||||
should be used for all pointer purposes.</li>
|
||||
should be used for all pointer purposes.</li>
|
||||
<li>caml_long_val receives a c_obj and returns a long. This
|
||||
should be used for most integral purposes.</li>
|
||||
should be used for most integral purposes.</li>
|
||||
<li>caml_val_ptr receives a void * and returns a c_obj.</li>
|
||||
<li>caml_val_bool receives a C int and returns a c_obj representing
|
||||
its bool value.</li>
|
||||
its bool value.</li>
|
||||
<li>caml_val_(u)?(char|short|int|long|float|double) receives an
|
||||
appropriate C value and returns a c_obj representing it.</li>
|
||||
appropriate C value and returns a c_obj representing it.</li>
|
||||
<li>caml_val_string receives a char * and returns a string value.</li>
|
||||
<li>caml_val_string_len receives a char * and a length and returns
|
||||
a string value.</li>
|
||||
a string value.</li>
|
||||
<li>caml_val_obj receives a void * and an object type and returns
|
||||
a C_obj, which contains a closure giving method access.</li>
|
||||
a C_obj, which contains a closure giving method access.</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
|
|
@ -544,24 +544,24 @@ into this type of function convenient.
|
|||
#include <stdio.h>
|
||||
|
||||
void printfloats( float *tab, int len ) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < len; i++ ) {
|
||||
printf( "%f ", tab[i] );
|
||||
}
|
||||
for( i = 0; i < len; i++ ) {
|
||||
printf( "%f ", tab[i] );
|
||||
}
|
||||
|
||||
printf( "\n" );
|
||||
printf( "\n" );
|
||||
}
|
||||
%}
|
||||
|
||||
%typemap(in) (float *tab, int len) {
|
||||
int i;
|
||||
/* $*1_type */
|
||||
$2 = caml_array_len($input);
|
||||
$1 = ($*1_type *)malloc( $2 * sizeof( float ) );
|
||||
for( i = 0; i < $2; i++ ) {
|
||||
$1[i] = caml_double_val(caml_array_nth($input,i));
|
||||
}
|
||||
int i;
|
||||
/* $*1_type */
|
||||
$2 = caml_array_len($input);
|
||||
$1 = ($*1_type *)malloc( $2 * sizeof( float ) );
|
||||
for( i = 0; i < $2; i++ ) {
|
||||
$1[i] = caml_double_val(caml_array_nth($input,i));
|
||||
}
|
||||
}
|
||||
|
||||
void printfloats( float *tab, int len );
|
||||
|
|
@ -640,7 +640,7 @@ length. Instead, use multiple returns, as in the argout_ref example.
|
|||
%include <stl.i>
|
||||
|
||||
namespace std {
|
||||
%template(StringVector) std::vector < string >;
|
||||
%template(StringVector) std::vector < string >;
|
||||
};
|
||||
|
||||
%include "example.h"
|
||||
|
|
@ -715,16 +715,16 @@ Here's a simple example using Trolltech's Qt Library:
|
|||
%}
|
||||
class QApplication {
|
||||
public:
|
||||
QApplication( int argc, char **argv );
|
||||
void setMainWidget( QWidget *widget );
|
||||
void exec();
|
||||
QApplication( int argc, char **argv );
|
||||
void setMainWidget( QWidget *widget );
|
||||
void exec();
|
||||
};
|
||||
|
||||
class QPushButton {
|
||||
public:
|
||||
QPushButton( char *str, QWidget *w );
|
||||
void resize( int x, int y );
|
||||
void show();
|
||||
QPushButton( char *str, QWidget *w );
|
||||
void resize( int x, int y );
|
||||
void show();
|
||||
};
|
||||
</pre></td></tr></table>
|
||||
|
||||
|
|
@ -848,9 +848,9 @@ let triangle_class pts ob meth args =
|
|||
"cover" ->
|
||||
(match args with
|
||||
C_list [ x_arg ; y_arg ] ->
|
||||
let xa = x_arg as float
|
||||
and ya = y_arg as float in
|
||||
(point_in_triangle pts xa ya) to bool
|
||||
let xa = x_arg as float
|
||||
and ya = y_arg as float in
|
||||
(point_in_triangle pts xa ya) to bool
|
||||
| _ -> raise (Failure "cover needs two double arguments."))
|
||||
| _ -> (invoke ob) meth args ;;
|
||||
|
||||
|
|
|
|||
|
|
@ -220,9 +220,9 @@ script such as the following:</p>
|
|||
# File : Makefile.PL
|
||||
use ExtUtils::MakeMaker;
|
||||
WriteMakefile(
|
||||
`NAME' => `example', # Name of package
|
||||
`LIBS' => [`-lm'], # Name of custom libraries
|
||||
`OBJECT' => `example.o example_wrap.o' # Object files
|
||||
`NAME' => `example', # Name of package
|
||||
`LIBS' => [`-lm'], # Name of custom libraries
|
||||
`OBJECT' => `example.o example_wrap.o' # Object files
|
||||
);
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -301,7 +301,7 @@ for a dynamic module, but change the link line to something like this:
|
|||
|
||||
<div class="code"><pre>
|
||||
$ gcc example.o example_wrap.o -L/usr/lib/perl/5.14/CORE \
|
||||
-lperl -lsocket -lnsl -lm -o myperl
|
||||
-lperl -lsocket -lnsl -lm -o myperl
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -892,9 +892,9 @@ To check to see if a value is the NULL pointer, use the
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
if (defined($ptr)) {
|
||||
print "Not a NULL pointer.";
|
||||
print "Not a NULL pointer.";
|
||||
} else {
|
||||
print "Is a NULL pointer.";
|
||||
print "Is a NULL pointer.";
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -917,9 +917,9 @@ dereference them as follows:
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
if ($$a == $$b) {
|
||||
print "a and b point to the same thing in C";
|
||||
print "a and b point to the same thing in C";
|
||||
} else {
|
||||
print "a and b point to different objects.";
|
||||
print "a and b point to different objects.";
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -978,7 +978,7 @@ accessor functions as described in the "SWIG Basics" chapter. For example,
|
|||
|
||||
<div class="code"><pre>
|
||||
struct Vector {
|
||||
double x,y,z;
|
||||
double x,y,z;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1259,17 +1259,17 @@ The following C++ operators are currently supported by the Perl module:
|
|||
</p>
|
||||
|
||||
<ul>
|
||||
<li>operator++ </li>
|
||||
<li>operator-- </li>
|
||||
<li>operator+ </li>
|
||||
<li>operator- </li>
|
||||
<li>operator* </li>
|
||||
<li>operator/ </li>
|
||||
<li>operator== </li>
|
||||
<li>operator!= </li>
|
||||
<li>operator% </li>
|
||||
<li>operator> </li>
|
||||
<li>operator< </li>
|
||||
<li>operator++</li>
|
||||
<li>operator--</li>
|
||||
<li>operator+</li>
|
||||
<li>operator-</li>
|
||||
<li>operator*</li>
|
||||
<li>operator/</li>
|
||||
<li>operator==</li>
|
||||
<li>operator!=</li>
|
||||
<li>operator%</li>
|
||||
<li>operator></li>
|
||||
<li>operator<</li>
|
||||
<li>operator and </li>
|
||||
<li>operator or </li>
|
||||
</ul>
|
||||
|
|
@ -1783,8 +1783,8 @@ you might define a typemap like this:
|
|||
%module example
|
||||
|
||||
%typemap(in) int {
|
||||
$1 = (int) SvIV($input);
|
||||
printf("Received an integer : %d\n", $1);
|
||||
$1 = (int) SvIV($input);
|
||||
printf("Received an integer : %d\n", $1);
|
||||
}
|
||||
...
|
||||
%inline %{
|
||||
|
|
@ -1829,8 +1829,8 @@ the typemap system follows <tt>typedef</tt> declarations. For example:
|
|||
<div class="targetlang">
|
||||
<pre>
|
||||
%typemap(in) int n {
|
||||
$1 = (int) SvIV($input);
|
||||
printf("n = %d\n",$1);
|
||||
$1 = (int) SvIV($input);
|
||||
printf("n = %d\n",$1);
|
||||
}
|
||||
%inline %{
|
||||
typedef int Integer;
|
||||
|
|
@ -2143,47 +2143,47 @@ reference to be used as a char ** datatype.
|
|||
|
||||
// This tells SWIG to treat char ** as a special case
|
||||
%typemap(in) char ** {
|
||||
AV *tempav;
|
||||
I32 len;
|
||||
int i;
|
||||
SV **tv;
|
||||
if (!SvROK($input))
|
||||
croak("Argument $argnum is not a reference.");
|
||||
if (SvTYPE(SvRV($input)) != SVt_PVAV)
|
||||
croak("Argument $argnum is not an array.");
|
||||
tempav = (AV*)SvRV($input);
|
||||
len = av_len(tempav);
|
||||
$1 = (char **) malloc((len+2)*sizeof(char *));
|
||||
for (i = 0; i <= len; i++) {
|
||||
tv = av_fetch(tempav, i, 0);
|
||||
$1[i] = (char *) SvPV(*tv,PL_na);
|
||||
}
|
||||
$1[i] = NULL;
|
||||
AV *tempav;
|
||||
I32 len;
|
||||
int i;
|
||||
SV **tv;
|
||||
if (!SvROK($input))
|
||||
croak("Argument $argnum is not a reference.");
|
||||
if (SvTYPE(SvRV($input)) != SVt_PVAV)
|
||||
croak("Argument $argnum is not an array.");
|
||||
tempav = (AV*)SvRV($input);
|
||||
len = av_len(tempav);
|
||||
$1 = (char **) malloc((len+2)*sizeof(char *));
|
||||
for (i = 0; i <= len; i++) {
|
||||
tv = av_fetch(tempav, i, 0);
|
||||
$1[i] = (char *) SvPV(*tv,PL_na);
|
||||
}
|
||||
$1[i] = NULL;
|
||||
};
|
||||
|
||||
// This cleans up the char ** array after the function call
|
||||
%typemap(freearg) char ** {
|
||||
free($1);
|
||||
free($1);
|
||||
}
|
||||
|
||||
// Creates a new Perl array and places a NULL-terminated char ** into it
|
||||
%typemap(out) char ** {
|
||||
AV *myav;
|
||||
SV **svs;
|
||||
int i = 0,len = 0;
|
||||
/* Figure out how many elements we have */
|
||||
while ($1[len])
|
||||
len++;
|
||||
svs = (SV **) malloc(len*sizeof(SV *));
|
||||
for (i = 0; i < len ; i++) {
|
||||
svs[i] = sv_newmortal();
|
||||
sv_setpv((SV*)svs[i],$1[i]);
|
||||
};
|
||||
myav = av_make(len,svs);
|
||||
free(svs);
|
||||
$result = newRV_noinc((SV*)myav);
|
||||
sv_2mortal($result);
|
||||
argvi++;
|
||||
AV *myav;
|
||||
SV **svs;
|
||||
int i = 0,len = 0;
|
||||
/* Figure out how many elements we have */
|
||||
while ($1[len])
|
||||
len++;
|
||||
svs = (SV **) malloc(len*sizeof(SV *));
|
||||
for (i = 0; i < len ; i++) {
|
||||
svs[i] = sv_newmortal();
|
||||
sv_setpv((SV*)svs[i],$1[i]);
|
||||
};
|
||||
myav = av_make(len,svs);
|
||||
free(svs);
|
||||
$result = newRV_noinc((SV*)myav);
|
||||
sv_2mortal($result);
|
||||
argvi++;
|
||||
}
|
||||
|
||||
// Now a few test functions
|
||||
|
|
@ -2240,12 +2240,12 @@ can be done using the <tt>EXTEND()</tt> macro as in:
|
|||
|
||||
<div class="code"><pre>
|
||||
%typemap(argout) int *OUTPUT {
|
||||
if (argvi >= items) {
|
||||
EXTEND(sp,1); /* Extend the stack by 1 object */
|
||||
}
|
||||
$result = sv_newmortal();
|
||||
sv_setiv($target,(IV) *($1));
|
||||
argvi++;
|
||||
if (argvi >= items) {
|
||||
EXTEND(sp,1); /* Extend the stack by 1 object */
|
||||
}
|
||||
$result = sv_newmortal();
|
||||
sv_setiv($target,(IV) *($1));
|
||||
argvi++;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2264,24 +2264,24 @@ its arguments. This example describes the implementation of the <tt>OUTPUT</tt>
|
|||
// an output value.
|
||||
|
||||
%typemap(argout) double *OUTPUT {
|
||||
$result = sv_newmortal();
|
||||
sv_setnv($result, *$input);
|
||||
argvi++; /* Increment return count -- important! */
|
||||
$result = sv_newmortal();
|
||||
sv_setnv($result, *$input);
|
||||
argvi++; /* Increment return count -- important! */
|
||||
}
|
||||
|
||||
// We don't care what the input value is. Ignore, but set to a temporary variable
|
||||
|
||||
%typemap(in,numinputs=0) double *OUTPUT(double junk) {
|
||||
$1 = &junk;
|
||||
$1 = &junk;
|
||||
}
|
||||
|
||||
// Now a function to test it
|
||||
%{
|
||||
/* Returns the first two input arguments */
|
||||
int multout(double a, double b, double *out1, double *out2) {
|
||||
*out1 = a;
|
||||
*out2 = b;
|
||||
return 0;
|
||||
*out1 = a;
|
||||
*out2 = b;
|
||||
return 0;
|
||||
};
|
||||
%}
|
||||
|
||||
|
|
@ -2377,7 +2377,7 @@ have a C function that modifies its arguments like this:
|
|||
|
||||
<div class="code"><pre>
|
||||
void add(double a, double b, double *c) {
|
||||
*c = a + b;
|
||||
*c = a + b;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2558,9 +2558,9 @@ Suppose you have the following SWIG interface file:
|
|||
<div class="code"><pre>
|
||||
%module example
|
||||
struct Vector {
|
||||
Vector(double x, double y, double z);
|
||||
~Vector();
|
||||
double x,y,z;
|
||||
Vector(double x, double y, double z);
|
||||
~Vector();
|
||||
double x,y,z;
|
||||
};
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2610,8 +2610,9 @@ sub DESTROY {
|
|||
my $self = tied(%{$_[0]});
|
||||
delete $ITERATORS{$self};
|
||||
if (exists $OWNER{$self}) {
|
||||
examplec::delete_Vector($self));
|
||||
delete $OWNER{$self};
|
||||
examplec::delete_Vector($self));
|
||||
delete $OWNER{$self};
|
||||
}
|
||||
}
|
||||
|
||||
sub FETCH {
|
||||
|
|
@ -2663,8 +2664,8 @@ $v->{x} = 7.5;
|
|||
|
||||
# Assignment of all members
|
||||
%$v = ( x=>3,
|
||||
y=>9,
|
||||
z=>-2);
|
||||
y=>9,
|
||||
z=>-2);
|
||||
|
||||
# Reading members
|
||||
$x = $v->{x};
|
||||
|
|
@ -2685,7 +2686,7 @@ problem---suppose you had a function like this:
|
|||
|
||||
<div class="code"><pre>
|
||||
Vector *Vector_get(Vector *v, int index) {
|
||||
return &v[i];
|
||||
return &v[i];
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2698,9 +2699,9 @@ Vector object:
|
|||
|
||||
<div class="code"><pre>
|
||||
Vector *new_Vector(double x, double y, double z) {
|
||||
Vector *v;
|
||||
v = new Vector(x,y,z); // Call C++ constructor
|
||||
return v;
|
||||
Vector *v;
|
||||
v = new Vector(x,y,z); // Call C++ constructor
|
||||
return v;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2770,10 +2771,10 @@ Suppose that we have a new object that looks like this:
|
|||
|
||||
<div class="code"><pre>
|
||||
struct Particle {
|
||||
Vector r;
|
||||
Vector v;
|
||||
Vector f;
|
||||
int type;
|
||||
Vector r;
|
||||
Vector v;
|
||||
Vector f;
|
||||
int type;
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2789,9 +2790,9 @@ look like this (along with some supporting code):
|
|||
package Particle;
|
||||
...
|
||||
%BLESSEDMEMBERS = (
|
||||
r => `Vector',
|
||||
v => `Vector',
|
||||
f => `Vector',
|
||||
r => `Vector',
|
||||
v => `Vector',
|
||||
f => `Vector',
|
||||
);
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2867,23 +2868,23 @@ interface file:
|
|||
|
||||
class Shape {
|
||||
public:
|
||||
virtual double area() = 0;
|
||||
virtual double perimeter() = 0;
|
||||
void set_location(double x, double y);
|
||||
virtual double area() = 0;
|
||||
virtual double perimeter() = 0;
|
||||
void set_location(double x, double y);
|
||||
};
|
||||
class Circle : public Shape {
|
||||
public:
|
||||
Circle(double radius);
|
||||
~Circle();
|
||||
double area();
|
||||
double perimeter();
|
||||
Circle(double radius);
|
||||
~Circle();
|
||||
double area();
|
||||
double perimeter();
|
||||
};
|
||||
class Square : public Shape {
|
||||
public:
|
||||
Square(double size);
|
||||
~Square();
|
||||
double area();
|
||||
double perimeter();
|
||||
Square(double size);
|
||||
~Square();
|
||||
double area();
|
||||
double perimeter();
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
|
|||
|
|
@ -136,8 +136,8 @@ least work for Linux though):
|
|||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
gcc `php-config --includes` -fpic -c example_wrap.c example.c
|
||||
gcc -shared example_wrap.o example.o -o example.so
|
||||
gcc `php-config --includes` -fpic -c example_wrap.c example.c
|
||||
gcc -shared example_wrap.o example.o -o example.so
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="Php_nn1_3">34.1.2 Using PHP Extensions</a></H3>
|
||||
|
|
@ -150,7 +150,7 @@ load it. To do this, add a line like this to the <tt>[PHP]</tt> section of
|
|||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
extension=/path/to/modulename.so
|
||||
extension=/path/to/modulename.so
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -165,7 +165,7 @@ PHP script which uses your extension:
|
|||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
dl("/path/to/modulename.so"); // Load the module
|
||||
dl("/path/to/modulename.so"); // Load the module
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -180,7 +180,7 @@ call for you if the extension isn't already loaded:
|
|||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
include("example.php");
|
||||
include("example.php");
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -249,7 +249,7 @@ For example,
|
|||
<div class="code"><pre>
|
||||
%module example
|
||||
|
||||
#define EASY_TO_MISPELL 0
|
||||
#define EASY_TO_MISPELL 0
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -262,9 +262,9 @@ accessed incorrectly in PHP,
|
|||
include("example.php");
|
||||
|
||||
if(EASY_TO_MISPEL) {
|
||||
....
|
||||
...
|
||||
} else {
|
||||
....
|
||||
...
|
||||
}
|
||||
|
||||
</pre>
|
||||
|
|
@ -303,7 +303,7 @@ is accessed as follows:
|
|||
<div class="code"><pre>
|
||||
include("example.php");
|
||||
print seki_get();
|
||||
seki_set( seki_get() * 2); # The C variable is now 4.
|
||||
seki_set( seki_get() * 2); # The C variable is now 4.
|
||||
print seki_get();
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -348,7 +348,7 @@ Will be accessed in PHP like this :
|
|||
include("example.php");
|
||||
$a = foo(2);
|
||||
$b = bar(3.5, -1.5);
|
||||
$c = bar(3.5); # Use default argument for 2nd parameter
|
||||
$c = bar(3.5); # Use default argument for 2nd parameter
|
||||
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -599,10 +599,10 @@ This interface file
|
|||
|
||||
class Vector {
|
||||
public:
|
||||
double x,y,z;
|
||||
Vector();
|
||||
~Vector();
|
||||
double magnitude();
|
||||
double x,y,z;
|
||||
Vector();
|
||||
~Vector();
|
||||
double magnitude();
|
||||
};
|
||||
|
||||
struct Complex {
|
||||
|
|
@ -722,7 +722,7 @@ returns the current value of the class variable. For example
|
|||
%module example
|
||||
|
||||
class Ko {
|
||||
static int threats;
|
||||
static int threats;
|
||||
};
|
||||
|
||||
</pre></div>
|
||||
|
|
|
|||
|
|
@ -466,9 +466,9 @@ $ swig -python example.i
|
|||
$ gcc example.c example_wrap.c \
|
||||
-Xlinker -export-dynamic \
|
||||
-DHAVE_CONFIG_H -I/usr/local/include/python2.1 \
|
||||
-I/usr/local/lib/python2.1/config \
|
||||
-L/usr/local/lib/python2.1/config -lpython2.1 -lm -ldl \
|
||||
-o mypython
|
||||
-I/usr/local/lib/python2.1/config \
|
||||
-L/usr/local/lib/python2.1/config -lpython2.1 -lm -ldl \
|
||||
-o mypython
|
||||
|
||||
</pre></div>
|
||||
<p>
|
||||
|
|
@ -1286,7 +1286,7 @@ a very natural interface. For example,
|
|||
|
||||
<div class="code"><pre>
|
||||
struct Vector {
|
||||
double x,y,z;
|
||||
double x,y,z;
|
||||
};
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -4310,8 +4310,8 @@ you might define a typemap like this:
|
|||
%module example
|
||||
|
||||
%typemap(in) int {
|
||||
$1 = (int) PyLong_AsLong($input);
|
||||
printf("Received an integer : %d\n",$1);
|
||||
$1 = (int) PyLong_AsLong($input);
|
||||
printf("Received an integer : %d\n",$1);
|
||||
}
|
||||
%inline %{
|
||||
extern int fact(int n);
|
||||
|
|
@ -4348,11 +4348,11 @@ You can refine this by supplying an optional parameter name. For example:
|
|||
%module example
|
||||
|
||||
%typemap(in) int nonnegative {
|
||||
$1 = (int) PyLong_AsLong($input);
|
||||
if ($1 < 0) {
|
||||
PyErr_SetString(PyExc_ValueError,"Expected a nonnegative value.");
|
||||
return NULL;
|
||||
}
|
||||
$1 = (int) PyLong_AsLong($input);
|
||||
if ($1 < 0) {
|
||||
PyErr_SetString(PyExc_ValueError,"Expected a nonnegative value.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
%inline %{
|
||||
extern int fact(int nonnegative);
|
||||
|
|
@ -4374,8 +4374,8 @@ the typemap system follows <tt>typedef</tt> declarations. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in) int n {
|
||||
$1 = (int) PyLong_AsLong($input);
|
||||
printf("n = %d\n",$1);
|
||||
$1 = (int) PyLong_AsLong($input);
|
||||
printf("n = %d\n",$1);
|
||||
}
|
||||
%inline %{
|
||||
typedef int Integer;
|
||||
|
|
@ -4685,11 +4685,11 @@ object to be used as a <tt>char **</tt> object.
|
|||
for (i = 0; i < size; i++) {
|
||||
PyObject *o = PyList_GetItem($input,i);
|
||||
if (PyString_Check(o))
|
||||
$1[i] = PyString_AsString(PyList_GetItem($input,i));
|
||||
$1[i] = PyString_AsString(PyList_GetItem($input,i));
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,"list must contain strings");
|
||||
free($1);
|
||||
return NULL;
|
||||
PyErr_SetString(PyExc_TypeError,"list must contain strings");
|
||||
free($1);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
$1[i] = 0;
|
||||
|
|
@ -4784,11 +4784,11 @@ previous example:
|
|||
for (i = 0; i < $1; i++) {
|
||||
PyObject *o = PyList_GetItem($input,i);
|
||||
if (PyString_Check(o))
|
||||
$2[i] = PyString_AsString(PyList_GetItem($input,i));
|
||||
$2[i] = PyString_AsString(PyList_GetItem($input,i));
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,"list must contain strings");
|
||||
free($2);
|
||||
return NULL;
|
||||
PyErr_SetString(PyExc_TypeError,"list must contain strings");
|
||||
free($2);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
$2[i] = 0;
|
||||
|
|
@ -4832,10 +4832,10 @@ arguments rather than in the return value of a function. For example:
|
|||
<div class="code"><pre>
|
||||
/* Returns a status value and two values in out1 and out2 */
|
||||
int spam(double a, double b, double *out1, double *out2) {
|
||||
... Do a bunch of stuff ...
|
||||
*out1 = result1;
|
||||
*out2 = result2;
|
||||
return status;
|
||||
... Do a bunch of stuff ...
|
||||
*out1 = result1;
|
||||
*out2 = result2;
|
||||
return status;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -4190,10 +4190,10 @@ this:
|
|||
<pre>function_name(int x, int y, Foo foo=nil, Bar bar=nil) -> bool
|
||||
|
||||
Parameters:
|
||||
x - int
|
||||
y - int
|
||||
foo - Foo
|
||||
bar - Bar</pre>
|
||||
x - int
|
||||
y - int
|
||||
foo - Foo
|
||||
bar - Bar</pre>
|
||||
</div>
|
||||
|
||||
<H4><a name="Ruby_nn70">38.8.2.5 %feature("autodoc", "docstring")</a></H4>
|
||||
|
|
@ -5251,8 +5251,7 @@ existing Ruby object to the destroyed C++ object and raise an exception.
|
|||
#include "example.h"
|
||||
%}
|
||||
|
||||
/* Specify that ownership is transferred to the zoo
|
||||
when calling add_animal */
|
||||
/* Specify that ownership is transferred to the zoo when calling add_animal */
|
||||
%apply SWIGTYPE *DISOWN { Animal* animal };
|
||||
|
||||
/* Track objects */
|
||||
|
|
|
|||
|
|
@ -1037,15 +1037,14 @@ expect :</p>
|
|||
<div class="targetlang"><pre>
|
||||
# Copy a file
|
||||
def filecopy(source,target):
|
||||
f1 = fopen(source,"r")
|
||||
f2 = fopen(target,"w")
|
||||
buffer = malloc(8192)
|
||||
nbytes = fread(buffer,8192,1,f1)
|
||||
while (nbytes > 0):
|
||||
fwrite(buffer,8192,1,f2)
|
||||
nbytes = fread(buffer,8192,1,f1)
|
||||
free(buffer)
|
||||
|
||||
f1 = fopen(source,"r")
|
||||
f2 = fopen(target,"w")
|
||||
buffer = malloc(8192)
|
||||
nbytes = fread(buffer,8192,1,f1)
|
||||
while (nbytes > 0):
|
||||
fwrite(buffer,8192,1,f2)
|
||||
nbytes = fread(buffer,8192,1,f1)
|
||||
free(buffer)
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -1315,10 +1314,10 @@ gets mapped to an underlying pair of set/get functions like this :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
Vector *unit_i_get() {
|
||||
return &unit_i;
|
||||
return &unit_i;
|
||||
}
|
||||
void unit_i_set(Vector *value) {
|
||||
unit_i = *value;
|
||||
unit_i = *value;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1605,11 +1604,11 @@ directive as shown :</p>
|
|||
<div class="code"><pre>
|
||||
// File : interface.i
|
||||
|
||||
int a; // Can read/write
|
||||
int a; // Can read/write
|
||||
%immutable;
|
||||
int b,c,d // Read only variables
|
||||
int b,c,d; // Read only variables
|
||||
%mutable;
|
||||
double x,y // read/write
|
||||
double x,y; // read/write
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -2129,8 +2128,8 @@ default arguments are optional in the target language. For example, this functio
|
|||
used in Tcl as follows :</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
% plot -3.4 7.5 # Use default value
|
||||
% plot -3.4 7.5 10 # set color to 10 instead
|
||||
% plot -3.4 7.5 # Use default value
|
||||
% plot -3.4 7.5 10 # set color to 10 instead
|
||||
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2320,7 +2319,7 @@ to an individual member. For example, the declaration :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
struct Vector {
|
||||
double x,y,z;
|
||||
double x,y,z;
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2330,22 +2329,22 @@ gets transformed into the following set of accessor functions :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
double Vector_x_get(struct Vector *obj) {
|
||||
return obj->x;
|
||||
return obj->x;
|
||||
}
|
||||
double Vector_y_get(struct Vector *obj) {
|
||||
return obj->y;
|
||||
return obj->y;
|
||||
}
|
||||
double Vector_z_get(struct Vector *obj) {
|
||||
return obj->z;
|
||||
return obj->z;
|
||||
}
|
||||
void Vector_x_set(struct Vector *obj, double value) {
|
||||
obj->x = value;
|
||||
obj->x = value;
|
||||
}
|
||||
void Vector_y_set(struct Vector *obj, double value) {
|
||||
obj->y = value;
|
||||
obj->y = value;
|
||||
}
|
||||
void Vector_z_set(struct Vector *obj, double value) {
|
||||
obj->z = value;
|
||||
obj->z = value;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2393,7 +2392,7 @@ programs :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
typedef struct {
|
||||
double x,y,z;
|
||||
double x,y,z;
|
||||
} Vector;
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2408,7 +2407,7 @@ that the use of <tt>typedef</tt> allows SWIG to drop the
|
|||
<div class="code">
|
||||
<pre>
|
||||
double Vector_x_get(Vector *obj) {
|
||||
return obj->x;
|
||||
return obj->x;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2418,7 +2417,7 @@ If two different names are used like this :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
typedef struct vector_struct {
|
||||
double x,y,z;
|
||||
double x,y,z;
|
||||
} Vector;
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2444,8 +2443,8 @@ will be released, and the new contents allocated. For example :</p>
|
|||
%module mymodule
|
||||
...
|
||||
struct Foo {
|
||||
char *name;
|
||||
...
|
||||
char *name;
|
||||
...
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2455,14 +2454,15 @@ This results in the following accessor functions :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
char *Foo_name_get(Foo *obj) {
|
||||
return Foo->name;
|
||||
return Foo->name;
|
||||
}
|
||||
|
||||
char *Foo_name_set(Foo *obj, char *c) {
|
||||
if (obj->name) free(obj->name);
|
||||
obj->name = (char *) malloc(strlen(c)+1);
|
||||
strcpy(obj->name,c);
|
||||
return obj->name;
|
||||
if (obj->name)
|
||||
free(obj->name);
|
||||
obj->name = (char *) malloc(strlen(c)+1);
|
||||
strcpy(obj->name,c);
|
||||
return obj->name;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2714,7 +2714,7 @@ the following declaration :</p>
|
|||
/* file : vector.h */
|
||||
...
|
||||
typedef struct Vector {
|
||||
double x,y,z;
|
||||
double x,y,z;
|
||||
} Vector;
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2732,23 +2732,23 @@ You can make a <tt>Vector</tt> look a lot like a class by writing a SWIG interfa
|
|||
|
||||
%include "vector.h" // Just grab original C header file
|
||||
%extend Vector { // Attach these functions to struct Vector
|
||||
Vector(double x, double y, double z) {
|
||||
Vector *v;
|
||||
v = (Vector *) malloc(sizeof(Vector));
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
v->z = z;
|
||||
return v;
|
||||
}
|
||||
~Vector() {
|
||||
free($self);
|
||||
}
|
||||
double magnitude() {
|
||||
return sqrt($self->x*$self->x+$self->y*$self->y+$self->z*$self->z);
|
||||
}
|
||||
void print() {
|
||||
printf("Vector [%g, %g, %g]\n", $self->x,$self->y,$self->z);
|
||||
}
|
||||
Vector(double x, double y, double z) {
|
||||
Vector *v;
|
||||
v = (Vector *) malloc(sizeof(Vector));
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
v->z = z;
|
||||
return v;
|
||||
}
|
||||
~Vector() {
|
||||
free($self);
|
||||
}
|
||||
double magnitude() {
|
||||
return sqrt($self->x*$self->x+$self->y*$self->y+$self->z*$self->z);
|
||||
}
|
||||
void print() {
|
||||
printf("Vector [%g, %g, %g]\n", $self->x,$self->y,$self->z);
|
||||
}
|
||||
};
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2787,12 +2787,12 @@ of the Vector structure. For example:</p>
|
|||
%}
|
||||
|
||||
typedef struct Vector {
|
||||
double x,y,z;
|
||||
%extend {
|
||||
Vector(double x, double y, double z) { ... }
|
||||
~Vector() { ... }
|
||||
...
|
||||
}
|
||||
double x,y,z;
|
||||
%extend {
|
||||
Vector(double x, double y, double z) { ... }
|
||||
~Vector() { ... }
|
||||
...
|
||||
}
|
||||
} Vector;
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2806,19 +2806,19 @@ example :</p>
|
|||
/* Vector methods */
|
||||
#include "vector.h"
|
||||
Vector *new_Vector(double x, double y, double z) {
|
||||
Vector *v;
|
||||
v = (Vector *) malloc(sizeof(Vector));
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
v->z = z;
|
||||
return v;
|
||||
Vector *v;
|
||||
v = (Vector *) malloc(sizeof(Vector));
|
||||
v->x = x;
|
||||
v->y = y;
|
||||
v->z = z;
|
||||
return v;
|
||||
}
|
||||
void delete_Vector(Vector *v) {
|
||||
free(v);
|
||||
free(v);
|
||||
}
|
||||
|
||||
double Vector_magnitude(Vector *v) {
|
||||
return sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
|
||||
return sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
|
||||
}
|
||||
|
||||
// File : vector.i
|
||||
|
|
@ -2829,13 +2829,13 @@ double Vector_magnitude(Vector *v) {
|
|||
%}
|
||||
|
||||
typedef struct Vector {
|
||||
double x,y,z;
|
||||
%extend {
|
||||
Vector(int,int,int); // This calls new_Vector()
|
||||
~Vector(); // This calls delete_Vector()
|
||||
double magnitude(); // This will call Vector_magnitude()
|
||||
...
|
||||
}
|
||||
double x,y,z;
|
||||
%extend {
|
||||
Vector(int,int,int); // This calls new_Vector()
|
||||
~Vector(); // This calls delete_Vector()
|
||||
double magnitude(); // This will call Vector_magnitude()
|
||||
...
|
||||
}
|
||||
} Vector;
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2847,13 +2847,13 @@ For example:
|
|||
|
||||
<div class="code"><pre>
|
||||
typedef struct Integer {
|
||||
int value;
|
||||
int value;
|
||||
} Int;
|
||||
%extend Integer { ... } /* Correct name */
|
||||
%extend Int { ... } /* Incorrect name */
|
||||
|
||||
struct Float {
|
||||
float value;
|
||||
float value;
|
||||
};
|
||||
typedef struct Float FloatValue;
|
||||
%extend Float { ... } /* Correct name */
|
||||
|
|
@ -2866,7 +2866,7 @@ There is one exception to this rule and that is when the struct is anonymously n
|
|||
|
||||
<div class="code"><pre>
|
||||
typedef struct {
|
||||
double value;
|
||||
double value;
|
||||
} Double;
|
||||
%extend Double { ... } /* Okay */
|
||||
</pre></div>
|
||||
|
|
@ -2975,13 +2975,13 @@ Occasionally, a C program will involve structures like this :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
typedef struct Object {
|
||||
int objtype;
|
||||
union {
|
||||
int ivalue;
|
||||
double dvalue;
|
||||
char *strvalue;
|
||||
void *ptrvalue;
|
||||
} intRep;
|
||||
int objtype;
|
||||
union {
|
||||
int ivalue;
|
||||
double dvalue;
|
||||
char *strvalue;
|
||||
void *ptrvalue;
|
||||
} intRep;
|
||||
} Object;
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2993,15 +2993,15 @@ following:</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
typedef union {
|
||||
int ivalue;
|
||||
double dvalue;
|
||||
char *strvalue;
|
||||
void *ptrvalue;
|
||||
int ivalue;
|
||||
double dvalue;
|
||||
char *strvalue;
|
||||
void *ptrvalue;
|
||||
} Object_intRep;
|
||||
|
||||
typedef struct Object {
|
||||
int objType;
|
||||
Object_intRep intRep;
|
||||
int objType;
|
||||
Object_intRep intRep;
|
||||
} Object;
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -3013,16 +3013,16 @@ structures. In this case, functions like this would be created :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
Object_intRep *Object_intRep_get(Object *o) {
|
||||
return (Object_intRep *) &o->intRep;
|
||||
return (Object_intRep *) &o->intRep;
|
||||
}
|
||||
int Object_intRep_ivalue_get(Object_intRep *o) {
|
||||
return o->ivalue;
|
||||
return o->ivalue;
|
||||
}
|
||||
int Object_intRep_ivalue_set(Object_intRep *o, int value) {
|
||||
return (o->ivalue = value);
|
||||
return (o->ivalue = value);
|
||||
}
|
||||
double Object_intRep_dvalue_get(Object_intRep *o) {
|
||||
return o->dvalue;
|
||||
return o->dvalue;
|
||||
}
|
||||
... etc ...
|
||||
|
||||
|
|
@ -3229,7 +3229,7 @@ program. For example :</p>
|
|||
%{
|
||||
/* Create a new vector */
|
||||
static Vector *new_Vector() {
|
||||
return (Vector *) malloc(sizeof(Vector));
|
||||
return (Vector *) malloc(sizeof(Vector));
|
||||
}
|
||||
|
||||
%}
|
||||
|
|
@ -3249,7 +3249,7 @@ there is a special inlined form of code block that is used as follows
|
|||
%inline %{
|
||||
/* Create a new vector */
|
||||
Vector *new_Vector() {
|
||||
return (Vector *) malloc(sizeof(Vector));
|
||||
return (Vector *) malloc(sizeof(Vector));
|
||||
}
|
||||
%}
|
||||
|
||||
|
|
@ -3275,7 +3275,7 @@ initialization on module loading, you could write this:
|
|||
|
||||
<div class="code"><pre>
|
||||
%init %{
|
||||
init_variables();
|
||||
init_variables();
|
||||
%}
|
||||
</pre></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -530,10 +530,10 @@ functions such as the following :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
List * new_List(void) {
|
||||
return new List;
|
||||
return new List;
|
||||
}
|
||||
void delete_List(List *l) {
|
||||
delete l;
|
||||
delete l;
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -874,7 +874,7 @@ All member functions are roughly translated into accessor functions like this :<
|
|||
|
||||
<div class="code"><pre>
|
||||
int List_search(List *obj, char *value) {
|
||||
return obj->search(value);
|
||||
return obj->search(value);
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -912,11 +912,11 @@ structures. A pair of accessor functions are effectively created. For example
|
|||
|
||||
<div class="code"><pre>
|
||||
int List_length_get(List *obj) {
|
||||
return obj->length;
|
||||
return obj->length;
|
||||
}
|
||||
int List_length_set(List *obj, int value) {
|
||||
obj->length = value;
|
||||
return value;
|
||||
obj->length = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -933,7 +933,7 @@ class List {
|
|||
public:
|
||||
...
|
||||
%immutable;
|
||||
int length;
|
||||
int length;
|
||||
%mutable;
|
||||
...
|
||||
};
|
||||
|
|
@ -1231,7 +1231,7 @@ into constants with the classname as a prefix. For example :</p>
|
|||
<div class="code"><pre>
|
||||
class Swig {
|
||||
public:
|
||||
enum {ALE, LAGER, PORTER, STOUT};
|
||||
enum {ALE, LAGER, PORTER, STOUT};
|
||||
};
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -1321,7 +1321,7 @@ a declaration like this :</p>
|
|||
<div class="code"><pre>
|
||||
class Foo {
|
||||
public:
|
||||
double bar(double &a);
|
||||
double bar(double &a);
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1331,7 +1331,7 @@ has a low-level accessor
|
|||
|
||||
<div class="code"><pre>
|
||||
double Foo_bar(Foo *obj, double *a) {
|
||||
obj->bar(*a);
|
||||
obj->bar(*a);
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1550,24 +1550,24 @@ the full C++ code has been omitted.</p>
|
|||
|
||||
class Shape {
|
||||
public:
|
||||
double x,y;
|
||||
virtual double area() = 0;
|
||||
virtual double perimeter() = 0;
|
||||
void set_location(double x, double y);
|
||||
double x,y;
|
||||
virtual double area() = 0;
|
||||
virtual double perimeter() = 0;
|
||||
void set_location(double x, double y);
|
||||
};
|
||||
class Circle : public Shape {
|
||||
public:
|
||||
Circle(double radius);
|
||||
~Circle();
|
||||
double area();
|
||||
double perimeter();
|
||||
Circle(double radius);
|
||||
~Circle();
|
||||
double area();
|
||||
double perimeter();
|
||||
};
|
||||
class Square : public Shape {
|
||||
public:
|
||||
Square(double size);
|
||||
~Square();
|
||||
double area();
|
||||
double perimeter();
|
||||
Square(double size);
|
||||
~Square();
|
||||
double area();
|
||||
double perimeter();
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -2615,7 +2615,7 @@ public:
|
|||
}
|
||||
Complex operator*(const Complex &c) const {
|
||||
return Complex(rpart*c.rpart - ipart*c.ipart,
|
||||
rpart*c.ipart + c.rpart*ipart);
|
||||
rpart*c.ipart + c.rpart*ipart);
|
||||
}
|
||||
Complex operator-() const {
|
||||
return Complex(-rpart, -ipart);
|
||||
|
|
@ -2788,17 +2788,17 @@ example :
|
|||
|
||||
class Vector {
|
||||
public:
|
||||
double x,y,z;
|
||||
Vector();
|
||||
~Vector();
|
||||
... bunch of C++ methods ...
|
||||
%extend {
|
||||
char *__str__() {
|
||||
static char temp[256];
|
||||
sprintf(temp,"[ %g, %g, %g ]", $self->x,$self->y,$self->z);
|
||||
return &temp[0];
|
||||
}
|
||||
}
|
||||
double x,y,z;
|
||||
Vector();
|
||||
~Vector();
|
||||
... bunch of C++ methods ...
|
||||
%extend {
|
||||
char *__str__() {
|
||||
static char temp[256];
|
||||
sprintf(temp,"[ %g, %g, %g ]", $self->x,$self->y,$self->z);
|
||||
return &temp[0];
|
||||
}
|
||||
}
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -4696,11 +4696,11 @@ public:
|
|||
return add_ref();
|
||||
}
|
||||
|
||||
int unref() const {
|
||||
int unref() const {
|
||||
if (ref_count() == 0 || del_ref() == 0 ) {
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return ref_count();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -102,8 +102,10 @@ Suppose you have an ordinary C function like this :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
int fact(int n) {
|
||||
if (n <= 1) return 1;
|
||||
else return n*fact(n-1);
|
||||
if (n <= 1)
|
||||
return 1;
|
||||
else
|
||||
return n*fact(n-1);
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -124,18 +126,17 @@ As an example, the Tcl wrapper function for the <tt>fact()</tt>
|
|||
function above example might look like the following : </p>
|
||||
|
||||
<div class="code"><pre>
|
||||
int wrap_fact(ClientData clientData, Tcl_Interp *interp,
|
||||
int argc, char *argv[]) {
|
||||
int result;
|
||||
int arg0;
|
||||
if (argc != 2) {
|
||||
interp->result = "wrong # args";
|
||||
return TCL_ERROR;
|
||||
}
|
||||
arg0 = atoi(argv[1]);
|
||||
result = fact(arg0);
|
||||
sprintf(interp->result,"%d", result);
|
||||
return TCL_OK;
|
||||
int wrap_fact(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
|
||||
int result;
|
||||
int arg0;
|
||||
if (argc != 2) {
|
||||
interp->result = "wrong # args";
|
||||
return TCL_ERROR;
|
||||
}
|
||||
arg0 = atoi(argv[1]);
|
||||
result = fact(arg0);
|
||||
sprintf(interp->result,"%d", result);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -149,9 +150,9 @@ requires code like the following :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
int Wrap_Init(Tcl_Interp *interp) {
|
||||
Tcl_CreateCommand(interp, "fact", wrap_fact, (ClientData) NULL,
|
||||
(Tcl_CmdDeleteProc *) NULL);
|
||||
return TCL_OK;
|
||||
Tcl_CreateCommand(interp, "fact", wrap_fact, (ClientData) NULL,
|
||||
(Tcl_CmdDeleteProc *) NULL);
|
||||
return TCL_OK;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -244,9 +245,9 @@ representation of a structure. For example,
|
|||
|
||||
<div class="code"><pre>
|
||||
struct Vector {
|
||||
Vector();
|
||||
~Vector();
|
||||
double x,y,z;
|
||||
Vector();
|
||||
~Vector();
|
||||
double x,y,z;
|
||||
};
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -299,9 +300,9 @@ have the following C++ definition :</p>
|
|||
<div class="code"><pre>
|
||||
class Vector {
|
||||
public:
|
||||
Vector();
|
||||
~Vector();
|
||||
double x,y,z;
|
||||
Vector();
|
||||
~Vector();
|
||||
double x,y,z;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -208,8 +208,8 @@ $ swig -tcl example.i
|
|||
$ gcc example.c example_wrap.c \
|
||||
-Xlinker -export-dynamic \
|
||||
-DHAVE_CONFIG_H -I/usr/local/include/ \
|
||||
-L/usr/local/lib -ltcl -lm -ldl \
|
||||
-o mytclsh
|
||||
-L/usr/local/lib -ltcl -lm -ldl \
|
||||
-o mytclsh
|
||||
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -626,11 +626,11 @@ CFLAGS = /Z7 /Od /c /nologo
|
|||
TCL_INCLUDES = -Id:\tcl8.0a2\generic -Id:\tcl8.0a2\win
|
||||
TCLLIB = d:\tcl8.0a2\win\tcl80.lib
|
||||
|
||||
tcl::
|
||||
..\..\swig -tcl -o $(WRAPFILE) $(INTERFACE)
|
||||
$(CC) $(CFLAGS) $(TCL_INCLUDES) $(SRCS) $(WRAPFILE)
|
||||
set LIB=$(TOOLS)\lib
|
||||
$(LINK) $(LOPT) -out:example.dll $(LIBS) $(TCLLIB) example.obj example_wrap.obj
|
||||
tcl:
|
||||
..\..\swig -tcl -o $(WRAPFILE) $(INTERFACE)
|
||||
$(CC) $(CFLAGS) $(TCL_INCLUDES) $(SRCS) $(WRAPFILE)
|
||||
set LIB=$(TOOLS)\lib
|
||||
$(LINK) $(LOPT) -out:example.dll $(LIBS) $(TCLLIB) example.obj example_wrap.obj
|
||||
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -981,7 +981,7 @@ This provides a very natural interface. For example,
|
|||
|
||||
<div class="code"><pre>
|
||||
struct Vector {
|
||||
double x,y,z;
|
||||
double x,y,z;
|
||||
};
|
||||
|
||||
</pre></div>
|
||||
|
|
@ -2466,8 +2466,9 @@ you might define a typemap like this:
|
|||
%module example
|
||||
|
||||
%typemap(in) int {
|
||||
if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR) return TCL_ERROR;
|
||||
printf("Received an integer : %d\n",$1);
|
||||
if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
printf("Received an integer : %d\n",$1);
|
||||
}
|
||||
%inline %{
|
||||
extern int fact(int n);
|
||||
|
|
@ -2504,8 +2505,9 @@ You can refine this by supplying an optional parameter name. For example:
|
|||
%module example
|
||||
|
||||
%typemap(in) int n {
|
||||
if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR) return TCL_ERROR;
|
||||
printf("n = %d\n",$1);
|
||||
if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
printf("n = %d\n",$1);
|
||||
}
|
||||
%inline %{
|
||||
extern int fact(int n);
|
||||
|
|
@ -2527,8 +2529,9 @@ the typemap system follows <tt>typedef</tt> declarations. For example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in) int n {
|
||||
if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR) return TCL_ERROR;
|
||||
printf("n = %d\n",$1);
|
||||
if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
printf("n = %d\n",$1);
|
||||
}
|
||||
%inline %{
|
||||
typedef int Integer;
|
||||
|
|
@ -2976,10 +2979,10 @@ work)
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in) int, short, long {
|
||||
int temp;
|
||||
if (Tcl_GetIntFromObj(interp, $input, &temp) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
$1 = ($1_ltype) temp;
|
||||
int temp;
|
||||
if (Tcl_GetIntFromObj(interp, $input, &temp) == TCL_ERROR)
|
||||
return TCL_ERROR;
|
||||
$1 = ($1_ltype) temp;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3154,8 +3157,8 @@ subdirectory which has the same name as the package. For example :
|
|||
|
||||
<div class="code"><pre>
|
||||
./example/
|
||||
pkgIndex.tcl # The file created by pkg_mkIndex
|
||||
example.so # The SWIG generated module
|
||||
pkgIndex.tcl # The file created by pkg_mkIndex
|
||||
example.so # The SWIG generated module
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -3265,14 +3268,14 @@ Our script allows easy array access as follows :
|
|||
<div class="code"><pre>
|
||||
set a [Array double 100] ;# Create a double [100]
|
||||
for {set i 0} {$i < 100} {incr i 1} { ;# Clear the array
|
||||
$a set $i 0.0
|
||||
$a set $i 0.0
|
||||
}
|
||||
$a set 3 3.1455 ;# Set an individual element
|
||||
set b [$a get 10] ;# Retrieve an element
|
||||
|
||||
set ia [Array int 50] ;# Create an int[50]
|
||||
for {set i 0} {$i < 50} {incr i 1} { ;# Clear it
|
||||
$ia set $i 0
|
||||
$ia set $i 0
|
||||
}
|
||||
$ia set 3 7 ;# Set an individual element
|
||||
set ib [$ia get 10] ;# Get an individual element
|
||||
|
|
|
|||
|
|
@ -3051,8 +3051,8 @@ For example, suppose you had a structure like this:
|
|||
|
||||
<div class="code"><pre>
|
||||
struct SomeObject {
|
||||
float value[4];
|
||||
...
|
||||
float value[4];
|
||||
...
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -3166,9 +3166,9 @@ checking the values of function arguments. For example:</p>
|
|||
%module math
|
||||
|
||||
%typemap(check) double posdouble {
|
||||
if ($1 < 0) {
|
||||
croak("Expecting a positive number");
|
||||
}
|
||||
if ($1 < 0) {
|
||||
croak("Expecting a positive number");
|
||||
}
|
||||
}
|
||||
|
||||
...
|
||||
|
|
@ -4511,22 +4511,22 @@ The following excerpt from the Python module illustrates this:
|
|||
/* Note: %typecheck(X) is a macro for %typemap(typecheck,precedence=X) */
|
||||
|
||||
%typecheck(SWIG_TYPECHECK_INTEGER)
|
||||
int, short, long,
|
||||
unsigned int, unsigned short, unsigned long,
|
||||
signed char, unsigned char,
|
||||
long long, unsigned long long,
|
||||
const int &, const short &, const long &,
|
||||
const unsigned int &, const unsigned short &, const unsigned long &,
|
||||
const long long &, const unsigned long long &,
|
||||
enum SWIGTYPE,
|
||||
bool, const bool &
|
||||
int, short, long,
|
||||
unsigned int, unsigned short, unsigned long,
|
||||
signed char, unsigned char,
|
||||
long long, unsigned long long,
|
||||
const int &, const short &, const long &,
|
||||
const unsigned int &, const unsigned short &, const unsigned long &,
|
||||
const long long &, const unsigned long long &,
|
||||
enum SWIGTYPE,
|
||||
bool, const bool &
|
||||
{
|
||||
$1 = (PyInt_Check($input) || PyLong_Check($input)) ? 1 : 0;
|
||||
}
|
||||
|
||||
%typecheck(SWIG_TYPECHECK_DOUBLE)
|
||||
float, double,
|
||||
const float &, const double &
|
||||
float, double,
|
||||
const float &, const double &
|
||||
{
|
||||
$1 = (PyFloat_Check($input) || PyInt_Check($input) || PyLong_Check($input)) ? 1 : 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -636,7 +636,7 @@ example. For example:
|
|||
PyObject *o = PyTuple_GetItem(varargs,i);
|
||||
if (!PyString_Check(o)) {
|
||||
PyErr_SetString(PyExc_ValueError,"Expected a string");
|
||||
free(argv);
|
||||
free(argv);
|
||||
return NULL;
|
||||
}
|
||||
argv[i] = PyString_AsString(o);
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ PYTHON_LIB: D:\python21\libs\python21.lib<br>
|
|||
<p>
|
||||
<b><tt>TCL_INCLUDE</tt></b> : Set this to the directory containing tcl.h<br>
|
||||
<b><tt>TCL_LIB</tt></b> : Set this to the TCL library including path for linking<p>
|
||||
Example using ActiveTcl 8.3.3.3 <br>
|
||||
Example using ActiveTcl 8.3.3.3<br>
|
||||
<tt>
|
||||
TCL_INCLUDE: D:\tcl\include<br>
|
||||
TCL_LIB: D:\tcl\lib\tcl83.lib<br>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue