Merge from trunk
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2009-sploving@12733 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
commit
e48855bfbf
60 changed files with 1099 additions and 545 deletions
|
|
@ -764,6 +764,8 @@
|
|||
<li><a href="Go.html#Go_templates">Go Templates</a>
|
||||
<li><a href="Go.html#Go_director_classes">Go Director Classes</a>
|
||||
<li><a href="Go.html#Go_primitive_type_mappings">Default Go primitive type mappings</a>
|
||||
<li><a href="#Go_output_arguments">Output arguments</a>
|
||||
<li><a href="#Go_adding_additional_code">Adding additional go code</a>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -1332,6 +1334,11 @@
|
|||
<li><a href="Python.html#Python_nn28">Further details on the Python class interface</a>
|
||||
<ul>
|
||||
<li><a href="Python.html#Python_nn29">Proxy classes</a>
|
||||
<li><a href="Python.html#Python_builtin_types">Built-in Types</a>
|
||||
<ul>
|
||||
<li><a href="Python.html#Python_builtin_limitations">Limitations</a>
|
||||
<li><a href="Python.html#Python_builtin_overloads">Operator overloads -- use them!</a>
|
||||
</ul>
|
||||
<li><a href="Python.html#Python_nn30">Memory management</a>
|
||||
<li><a href="Python.html#Python_nn31">Python 2.2 and classic classes</a>
|
||||
</ul>
|
||||
|
|
@ -1684,4 +1691,3 @@
|
|||
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
||||
|
|
|
|||
|
|
@ -2754,15 +2754,16 @@ int Python::top(Node *n) {
|
|||
|
||||
|
||||
<p>
|
||||
Within SWIG wrappers, there are four main sections. These are (in order)
|
||||
Within SWIG wrappers, there are five main sections. These are (in order)
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>runtime: This section has most of the common SWIG runtime code
|
||||
<li>header: This section holds declarations and inclusions from the .i file
|
||||
<li>wrapper: This section holds all the wrappering code
|
||||
<li>begin: This section is a placeholder for users to put code at the beginning of the C/C++ wrapper file.
|
||||
<li>runtime: This section has most of the common SWIG runtime code.
|
||||
<li>header: This section holds declarations and inclusions from the .i file.
|
||||
<li>wrapper: This section holds all the wrappering code.
|
||||
<li>init: This section holds the module initalisation function
|
||||
(the entry point for the interpreter)
|
||||
(the entry point for the interpreter).
|
||||
</ul>
|
||||
<p>
|
||||
Different parts of the SWIG code will fill different sections,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
<li><a href="#Go_templates">Go Templates</a>
|
||||
<li><a href="#Go_director_classes">Go Director Classes</a>
|
||||
<li><a href="#Go_primitive_type_mappings">Default Go primitive type mappings</a>
|
||||
<li><a href="#Go_output_arguments">Output arguments</a>
|
||||
<li><a href="#Go_adding_additional_code">Adding additional go code</a>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -273,7 +275,7 @@ class.
|
|||
|
||||
<p>
|
||||
SWIG will represent static methods of C++ classes as ordinary Go
|
||||
functions. SWIG will use names like <tt>ClassName_MethodName</tt>.
|
||||
functions. SWIG will use names like <tt>ClassNameMethodName</tt>.
|
||||
SWIG will give static members getter and setter functions with names
|
||||
like <tt>GetClassName_VarName</tt>.
|
||||
</p>
|
||||
|
|
@ -289,6 +291,37 @@ to <tt>reinterpret_cast</tt>. This should only be used for very
|
|||
special cases, such as where C++ would use a <tt>dynamic_cast</tt>.
|
||||
</p>
|
||||
|
||||
<p>Note that C++ pointers to compound objects are represented in go as objects
|
||||
themselves, not as go pointers. So, for example, if you wrap the following
|
||||
function:</p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
class MyClass {
|
||||
int MyMethod();
|
||||
static MyClass *MyFactoryFunction();
|
||||
};
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
<p>You will get go code that looks like this:</p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
type MyClass interface {
|
||||
Swigcptr() uintptr
|
||||
SwigIsMyClass()
|
||||
MyMethod() int
|
||||
}
|
||||
|
||||
MyClassMyFactoryFunction() MyClass {
|
||||
// swig magic here
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
<p>Note that the factory function does not return a go pointer; it actually
|
||||
returns a go interface. If the returned pointer can be null, you can check
|
||||
for this by calling the Swigcptr() method.
|
||||
</p>
|
||||
|
||||
<H4><a name="Go_class_inheritance"></a>21.3.5.1 Go Class Inheritance</H4>
|
||||
|
||||
|
||||
|
|
@ -459,5 +492,130 @@ that typemap, or add new values, to control how C/C++ types are mapped
|
|||
into Go types.
|
||||
</p>
|
||||
|
||||
<H3><a name="Go_output_arguments"></a>21.3.9 Output arguments</H3>
|
||||
|
||||
|
||||
<p>Because of limitations in the way output arguments are processed in swig,
|
||||
a function with output arguments will not have multiple return values.
|
||||
Instead, you must pass a pointer into the C++ function to tell it where to
|
||||
store the ouput value. In go, you supply a slice in the place of the output
|
||||
argument.</p>
|
||||
|
||||
<p>For example, suppose you were trying to wrap the modf() function in the
|
||||
C math library which splits x into integral and fractional parts (and
|
||||
returns the integer part in one of its parameters):<p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
double modf(double x, double *ip);
|
||||
</pre>
|
||||
</div>
|
||||
<p>You could wrap it with SWIG as follows:</p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
%include <typemaps.i>
|
||||
double modf(double x, double *OUTPUT);
|
||||
</pre>
|
||||
</div>
|
||||
<p>or you can use the <code>%apply</code> directive:</p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
%include <typemaps.i>
|
||||
%apply double *OUTPUT { double *ip };
|
||||
double modf(double x, double *ip);
|
||||
</pre>
|
||||
</div>
|
||||
<p>In Go you would use it like this:</p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
ptr := []float64{0.0}
|
||||
fraction := modulename.Modf(5.0, ptr)
|
||||
</pre>
|
||||
</div>
|
||||
<p>Since this is ugly, you may want to wrap the swig-generated API with
|
||||
some <a href="#Embedded_go_code">additional functions written in go</a> that
|
||||
hide the ugly details.</p>
|
||||
|
||||
<p>There are no <code>char *OUTPUT</code> typemaps. However you can
|
||||
apply the <code>signed char *</code> typemaps instead:<p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
%include <typemaps.i>
|
||||
%apply signed char *OUTPUT {char *output};
|
||||
void f(char *output);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<H3><a name="Go_adding_additional_code"></a>21.3.10 Adding additional go code</H3>
|
||||
|
||||
<p>Often the APIs generated by swig are not very natural in go, especially if
|
||||
there are output arguments. You can
|
||||
insert additional go wrapping code to add new APIs
|
||||
with <code>%insert(go_wrapper)</code>, like this:</p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
%include <typemaps.i>
|
||||
// Change name of what swig generates to Wrapped_modf. This function will
|
||||
// have the following signature in go:
|
||||
// func Wrapped_modf(float64, []float64) float64
|
||||
%rename(wrapped_modf) modf(double x, double *ip);
|
||||
|
||||
%apply double *OUTPUT { double *ip };
|
||||
double modf(double x, double *ip);
|
||||
|
||||
%insert(go_wrapper) %{
|
||||
|
||||
// The improved go interface to this function, which has two return values,
|
||||
// in the more natural go idiom:
|
||||
func Modf(x float64) (fracPart float64, intPart float64) {
|
||||
ip := []float64{0.0}
|
||||
fracPart = Wrapped_modf(x, ip)
|
||||
intPart = ip[0]
|
||||
return
|
||||
}
|
||||
|
||||
%}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>For classes, since swig generates an interface, you can add additional
|
||||
methods by defining another interface that includes the swig-generated
|
||||
interface. For example,</p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
%rename(Wrapped_MyClass) MyClass;
|
||||
%rename(Wrapped_GetAValue) MyClass::GetAValue(int *x);
|
||||
%apply int *OUTPUT { int *x };
|
||||
|
||||
class MyClass {
|
||||
public:
|
||||
MyClass();
|
||||
int AFineMethod(const char *arg); // Swig's wrapping is fine for this one.
|
||||
bool GetAValue(int *x);
|
||||
};
|
||||
|
||||
%insert(go_wrapper) %{
|
||||
|
||||
type MyClass interface {
|
||||
Wrapped_MyClass
|
||||
GetAValue() (int, bool)
|
||||
}
|
||||
|
||||
func (arg SwigcptrWrapped_MyClass) GetAValue() (int, bool) {
|
||||
ip := []int{0}
|
||||
ok := arg.Wrapped_GetAValue(ip)
|
||||
return ip[0], ok
|
||||
}
|
||||
|
||||
%}
|
||||
</pre>
|
||||
</div>
|
||||
<p>Of course, if you have to rewrite most of the methods, instead of just a
|
||||
few, then you might as well define your own struct that includes the
|
||||
swig-wrapped object, instead of adding methods to the swig-generated object.</p>
|
||||
|
||||
<p>This only works if your wrappers do not need to import other go modules.
|
||||
There is at present no way to insert import statements in the correct place
|
||||
in swig-generated go. If you need to do that, you must put your go code
|
||||
in a separate file.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,11 @@
|
|||
<li><a href="#Python_nn28">Further details on the Python class interface</a>
|
||||
<ul>
|
||||
<li><a href="#Python_nn29">Proxy classes</a>
|
||||
<li><a href="#Python_BuiltinClasses">Built-in classes</a>
|
||||
<li><a href="#Python_builtin_types">Built-in Types</a>
|
||||
<ul>
|
||||
<li><a href="#Python_builtin_limitations">Limitations</a>
|
||||
<li><a href="#Python_builtin_overloads">Operator overloads -- use them!</a>
|
||||
</ul>
|
||||
<li><a href="#Python_nn30">Memory management</a>
|
||||
<li><a href="#Python_nn31">Python 2.2 and classic classes</a>
|
||||
</ul>
|
||||
|
|
@ -2210,7 +2214,7 @@ unacceptable for a high-performance library. The new <tt>-builtin</tt>
|
|||
option instructs SWIG to forego the use of proxy classes, and instead
|
||||
create wrapped types as new built-in Python types. When this option is used,
|
||||
the following section ("Proxy classes") does not apply. Details on the use of
|
||||
the <tt>-builtin</tt> option are in the <a href="#Python_BuiltinClasses">Built-in Classes</a>
|
||||
the <tt>-builtin</tt> option are in the <a href="#Python_builtin_types">Built-in Types</a>
|
||||
section.
|
||||
</p>
|
||||
|
||||
|
|
@ -2303,7 +2307,8 @@ you can attach new Python methods to the class and you can even inherit from it
|
|||
by Python built-in types until Python 2.2).
|
||||
</p>
|
||||
|
||||
<H3><a name="Python_BuiltinClasses"></a>33.4.2 Built-in Classes</H3>
|
||||
<H3><a name="Python_builtin_types"></a>33.4.2 Built-in Types</H3>
|
||||
|
||||
|
||||
<p>
|
||||
The <tt>-builtin</tt> option provides a significant performance improvement
|
||||
|
|
@ -2346,23 +2351,26 @@ please refer to the python documentation:</p>
|
|||
|
||||
<p><a href="http://docs.python.org/extending/newtypes.html">http://docs.python.org/extending/newtypes.html</a></p>
|
||||
|
||||
<H4>33.4.2.1 Limitations</H4>
|
||||
<H4><a name="Python_builtin_limitations"></a>33.4.2.1 Limitations</H4>
|
||||
|
||||
|
||||
<p>Use of the <tt>-builtin</tt> option implies a couple of limitations:
|
||||
<ul>
|
||||
<li><p>python version support:</p></li>
|
||||
<ul>
|
||||
<li>Versions 2.5 and up are fully supported</li>
|
||||
<li>Versions 2.3 and 2.4 are mostly supported; there are problems with director classes and/or sub-classing a wrapped type in python.</li>
|
||||
<li>Versions older than 2.3 are not supported.</li>
|
||||
</ul>
|
||||
<li><p>Some legacy syntax is no longer supported; in particular:</p></li>
|
||||
<ul>
|
||||
<li>The functional interface is no longer exposed. For example, you may no longer call <tt>Whizzo.new_CrunchyFrog()</tt>. Instead, you must use <tt>Whizzo.CrunchyFrog()</tt>.</li>
|
||||
<li>Static member variables are no longer accessed through the 'cvar' field (e.g., <tt>Dances.cvar.FishSlap</tt>).
|
||||
They are instead accessed in the idiomatic way (<tt>Dances.FishSlap</tt>).</li>
|
||||
</ul>
|
||||
<li><p>Wrapped types may not be raised as python exceptions. Here's why: the python internals expect that all sub-classes of Exception will have this struct layout:</p>
|
||||
<li><p>python version support:</p>
|
||||
<ul>
|
||||
<li>Versions 2.5 and up are fully supported</li>
|
||||
<li>Versions 2.3 and 2.4 are mostly supported; there are problems with director classes and/or sub-classing a wrapped type in python.</li>
|
||||
<li>Versions older than 2.3 are not supported.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p>Some legacy syntax is no longer supported; in particular:</p>
|
||||
<ul>
|
||||
<li>The functional interface is no longer exposed. For example, you may no longer call <tt>Whizzo.new_CrunchyFrog()</tt>. Instead, you must use <tt>Whizzo.CrunchyFrog()</tt>.</li>
|
||||
<li>Static member variables are no longer accessed through the 'cvar' field (e.g., <tt>Dances.cvar.FishSlap</tt>).
|
||||
They are instead accessed in the idiomatic way (<tt>Dances.FishSlap</tt>).</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p>Wrapped types may not be raised as python exceptions. Here's why: the python internals expect that all sub-classes of Exception will have this struct layout:</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
|
|
@ -2420,15 +2428,10 @@ class MyPyException (Exception) :
|
|||
</pre>
|
||||
</div>
|
||||
</li>
|
||||
<li><p>Reverse binary operators (e.g., <tt>__radd__</tt>) are not supported.</p></li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To illustrate the last point, if you have a wrapped class called <tt>MyString</tt>,
|
||||
<li><p>Reverse binary operators (e.g., <tt>__radd__</tt>) are not supported.</p>
|
||||
<p>To illustrate this point, if you have a wrapped class called <tt>MyString</tt>,
|
||||
and you want to use instances of <tt>MyString</tt> interchangeably with native python
|
||||
strings, you can define an <tt>'operator+ (const char*)'</tt> method :
|
||||
</p>
|
||||
strings, you can define an <tt>'operator+ (const char*)'</tt> method :</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
|
|
@ -2472,8 +2475,52 @@ episode = "Dead " + mystr
|
|||
The above code fails, because the first operand -- a native python string --
|
||||
doesn't know how to add an instance of <tt>MyString</tt> to itself.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li><p>If you have multiple SWIG modules that share type information (<a href="Modules.html#Modules_nn2">more info</a>),
|
||||
the <tt>-builtin</tt> option requiress a bit of extra discipline to ensure that base classes are initialized before derived classes. Specifically:</p>
|
||||
<ul>
|
||||
<li><p>There must be an unambiguous dependency graph for the modules.</p></li>
|
||||
<li><p>Module dependencies must be explicitly stated with <tt>%import</tt> statements in the SWIG interface file.</p>
|
||||
</ul>
|
||||
|
||||
<p>As an example, suppose module <tt>A</tt> has this interface in <tt>A.i</tt> :</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%module "A";
|
||||
|
||||
class Base {
|
||||
...
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>If you want to wrap another module containing a class that inherits from <tt>A</tt>, this is how it would look :</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%module "B";
|
||||
|
||||
%import "A.i"
|
||||
|
||||
class Derived : public Base {
|
||||
...
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>The <tt>import "A.i"</tt> statement is required, because module <tt>B</tt> depends on module <tt>A</tt>.</p>
|
||||
|
||||
<p>As long as you obey these requirements, your python code may import the modules in any order :</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
import B
|
||||
import A
|
||||
|
||||
assert(issubclass(B.Derived, A.Base))
|
||||
</pre></div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<H4><a name="Python_builtin_overloads"></a>33.4.2.2 Operator overloads -- use them!</H4>
|
||||
|
||||
<H4>33.4.2.2 Operator overloads -- use them!</H4>
|
||||
|
||||
<p>The entire justification for the <tt>-builtin</tt> option is improved
|
||||
performance. To that end, the best way to squeeze maximum performance out
|
||||
|
|
@ -2491,10 +2538,10 @@ slot entries. For example, suppose you have this class:
|
|||
<pre>
|
||||
class Twit {
|
||||
public:
|
||||
Twit operator+ (const Twit& twit) const;
|
||||
Twit operator+ (const Twit& twit) const;
|
||||
|
||||
// Forward to operator+
|
||||
Twit add (const Twit& twit) const
|
||||
Twit add (const Twit& twit) const
|
||||
{ return *this + twit; }
|
||||
};
|
||||
</pre>
|
||||
|
|
@ -2575,6 +2622,7 @@ structs.
|
|||
|
||||
<H3><a name="Python_nn30"></a>33.4.3 Memory management</H3>
|
||||
|
||||
|
||||
<p>NOTE: Although this section refers to proxy objects, everything here also applies
|
||||
when the <tt>-builtin</tt> option is used.</p>
|
||||
|
||||
|
|
@ -5257,7 +5305,8 @@ all overloaded functions share the same function in SWIG generated proxy class.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
For detailed usage of function annotation, see PEP 3107.
|
||||
For detailed usage of function annotation, see
|
||||
<a href="http://www.python.org/dev/peps/pep-3107/">PEP 3107</a>.
|
||||
</p>
|
||||
|
||||
<H3><a name="Python_nn75"></a>33.12.2 Buffer interface</H3>
|
||||
|
|
@ -5449,7 +5498,8 @@ used to define an abstract base class for your own C++ class:
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
For details of abstract base class, please see PEP 3119.
|
||||
For details of abstract base class, please see
|
||||
<a href="http://www.python.org/dev/peps/pep-3119/">PEP 3119</a>.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -3034,14 +3034,15 @@ output of SWIG is structured first.</p>
|
|||
|
||||
|
||||
<p>
|
||||
When SWIG creates its output file, it is broken up into four sections
|
||||
When SWIG creates its output file, it is broken up into five sections
|
||||
corresponding to runtime code, headers, wrapper functions, and module
|
||||
initialization code (in that order).
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><b>Begin section</b>. <br>
|
||||
A placeholder to put code at the beginning of the C/C++ wrapper file.
|
||||
A placeholder for users to put code at the beginning of the C/C++ wrapper file.
|
||||
This is most often used to define preprocessor macros that are used in later sections.
|
||||
</li>
|
||||
|
||||
<li><b>Runtime code</b>. <br>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<body bgcolor="#ffffff">
|
||||
<H1><a name="Sections"></a>SWIG-2.0 Documentation</H1>
|
||||
|
||||
Last update : SWIG-2.0.4 (in progress)
|
||||
Last update : SWIG-2.0.5 (in progress)
|
||||
|
||||
<H2>Sections</H2>
|
||||
|
||||
|
|
|
|||
|
|
@ -331,33 +331,82 @@ int open(const char *path, int oflags, int mode = 0);
|
|||
<p>
|
||||
In this case, <tt>%varargs</tt> is simply providing more specific information about the
|
||||
extra arguments that might be passed to a function.
|
||||
If the parameters to a varargs function are of uniform type, <tt>%varargs</tt> can also
|
||||
If the arguments to a varargs function are of uniform type, <tt>%varargs</tt> can also
|
||||
accept a numerical argument count as follows:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%varargs(10,char *arg = NULL) execlp;
|
||||
%varargs(3, char *str = NULL) execlp;
|
||||
...
|
||||
int execlp(const char *path, const char *arg1, ...);
|
||||
int execlp(const char *path, const char *arg, ...);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This would wrap <tt>execlp()</tt> as a function that accepted up to 10 optional arguments.
|
||||
and is effectively seen as:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
int execlp(const char *path, const char *arg,
|
||||
char *str1 = NULL,
|
||||
char *str2 = NULL,
|
||||
char *str3 = NULL);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This would wrap <tt>execlp()</tt> as a function that accepted up to 3 optional arguments.
|
||||
Depending on the application, this may be more than enough for practical purposes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Argument replacement is most appropriate in cases where the types of
|
||||
the extra arguments is uniform and the maximum number of arguments is
|
||||
known. When replicated argument replacement is used, at least one extra
|
||||
argument is added to the end of the arguments when making the function call.
|
||||
This argument serves as a sentinel to make sure the list is properly terminated.
|
||||
It has the same value as that supplied to the <tt>%varargs</tt> directive.
|
||||
The handling of <a href="SWIGPlus.html#SWIGPlus_default_args">default arguments</a> can be changed via the
|
||||
<tt>compactdefaultargs</tt> feature. If this feature is used, for example
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%feature("compactdefaultargs") execlp;
|
||||
%varargs(3, char *str = NULL) execlp;
|
||||
...
|
||||
int execlp(const char *path, const char *arg, ...);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
a call from the target language which does not provide the maximum number of arguments, such as,
|
||||
<tt>execlp("a", "b", "c")</tt>
|
||||
will generate C code which includes the missing default values, that is, <tt>execlp("a", "b", "c", NULL, NULL)</tt>.
|
||||
If <tt>compactdefaultargs</tt> is not used, then the generated code will be
|
||||
<tt>execlp("a", "b", "c")</tt>. The former is useful for helping providing a sentinel to terminate the argument list.
|
||||
However, this is not guaranteed, for example when a user passes a non-NULL value for all the parameters.
|
||||
When using <tt>compactdefaultargs</tt> it is possible to guarantee the NULL sentinel is passed through the,
|
||||
<tt>numinputs=0</tt> <a href="Typemaps.html#Typemaps_nn26">'in' typemap attribute</a>, naming the <b>last parameter</b>.
|
||||
For example,
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%feature("compactdefaultargs") execlp;
|
||||
%varargs(3, char *str = NULL) execlp;
|
||||
%typemap(in, numinputs=0) char *str3 ""
|
||||
...
|
||||
int execlp(const char *path, const char *arg, ...);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Note that <tt>str3</tt> is the name of the last argument, as we have used <tt>%vargars</tt> with 3.
|
||||
Now <tt>execlp("a", "b", "c", "d", "e")</tt> will result in an error as one too many arguments has been passed,
|
||||
as now only 2 additional 'str' arguments can be passed with the 3rd one always using the specified default <tt>NULL</tt>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Argument replacement is most appropriate in cases where the types of
|
||||
the extra arguments are uniform and the maximum number of arguments are
|
||||
known.
|
||||
Argument replacement is not as useful when working with functions that accept
|
||||
mixed argument types such as <tt>printf()</tt>. Providing general purpose
|
||||
wrappers to such functions presents special problems (covered shortly).
|
||||
|
|
@ -461,23 +510,36 @@ like this:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in) (...)(char *args[10]) {
|
||||
int i;
|
||||
int argc;
|
||||
for (i = 0; i < 10; i++) args[i] = 0;
|
||||
argc = PyTuple_Size(varargs);
|
||||
if (argc > 10) {
|
||||
PyErr_SetString(PyExc_ValueError,"Too many arguments");
|
||||
int i;
|
||||
int argc;
|
||||
for (i = 0; i < 10; i++) args[i] = 0;
|
||||
argc = PyTuple_Size(varargs);
|
||||
if (argc > 10) {
|
||||
PyErr_SetString(PyExc_ValueError, "Too many arguments");
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < argc; i++) {
|
||||
PyObject *pyobj = PyTuple_GetItem(varargs, i);
|
||||
char *str = 0;
|
||||
%#if PY_VERSION_HEX>=0x03000000
|
||||
PyObject *pystr;
|
||||
if (!PyUnicode_Check(pyobj)) {
|
||||
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < argc; i++) {
|
||||
PyObject *o = PyTuple_GetItem(varargs,i);
|
||||
if (!PyString_Check(o)) {
|
||||
PyErr_SetString(PyExc_ValueError,"Expected a string");
|
||||
return NULL;
|
||||
}
|
||||
args[i] = PyString_AsString(o);
|
||||
pystr = PyUnicode_AsUTF8String(pyobj);
|
||||
str = PyBytes_AsString(pystr);
|
||||
Py_XDECREF(pystr);
|
||||
%#else
|
||||
if (!PyString_Check(pyobj)) {
|
||||
PyErr_SetString(PyExc_ValueError, "Expected a string");
|
||||
return NULL;
|
||||
}
|
||||
$1 = (void *) args;
|
||||
str = PyString_AsString(pyobj);
|
||||
%#endif
|
||||
args[i] = str;
|
||||
}
|
||||
$1 = (void *) args;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue