Merge branch 'tleonhardt-python_threads'
* tleonhardt-python_threads: Style fixes for Python threads documentation changes Finished updating Python docs for -threads option Started making changes to Python.html to document support for multithreaded Python SWIG applications.
This commit is contained in:
commit
f0f2fd2dae
2 changed files with 198 additions and 87 deletions
|
|
@ -1614,6 +1614,11 @@
|
|||
<li><a href="Python.html#Python_nn77">Byte string output conversion</a>
|
||||
<li><a href="Python.html#Python_2_unicode">Python 2 Unicode</a>
|
||||
</ul>
|
||||
<li><a href="Python.html#Python_multithreaded">Support for Multithreaded Applications</a>
|
||||
<ul>
|
||||
<li><a href="Python.html#Python_thread_UI">UI for Enabling Multithreading Support</a>
|
||||
<li><a href="Python.html#Python_thread_performance">Multithread Performance</a>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- INDEX -->
|
||||
|
|
|
|||
|
|
@ -133,6 +133,11 @@
|
|||
<li><a href="#Python_nn77">Byte string output conversion</a>
|
||||
<li><a href="#Python_2_unicode">Python 2 Unicode</a>
|
||||
</ul>
|
||||
<li><a href="#Python_multithreaded">Support for Multithreaded Applications</a>
|
||||
<ul>
|
||||
<li><a href="#Python_thread_UI">UI for Enabling Multithreading Support</a>
|
||||
<li><a href="#Python_thread_performance">Multithread Performance</a>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- INDEX -->
|
||||
|
|
@ -162,7 +167,7 @@ Basics</a>" chapter.
|
|||
|
||||
<p>
|
||||
To build Python extension modules, SWIG uses a layered approach in which
|
||||
parts of the extension module are defined in C and other parts are
|
||||
parts of the extension module are defined in C and other parts are
|
||||
defined in Python. The C layer contains low-level wrappers whereas Python code
|
||||
is used to define high-level features.
|
||||
</p>
|
||||
|
|
@ -395,9 +400,9 @@ $ gcc -shared example.o example_wrap.o -o _example.so
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
The exact commands for doing this vary from platform to platform.
|
||||
However, SWIG tries to guess the right options when it is installed. Therefore,
|
||||
you may want to start with one of the examples in the <tt>SWIG/Examples/python</tt>
|
||||
The exact commands for doing this vary from platform to platform.
|
||||
However, SWIG tries to guess the right options when it is installed. Therefore,
|
||||
you may want to start with one of the examples in the <tt>SWIG/Examples/python</tt>
|
||||
directory. If that doesn't work, you will need to read the man-pages for
|
||||
your compiler and linker to get the right set of options. You might also
|
||||
check the <a href="https://github.com/swig/swig/wiki">SWIG Wiki</a> for
|
||||
|
|
@ -409,7 +414,7 @@ When linking the module, <b>the name of the output file has to match the name
|
|||
of the module prefixed by an underscore</b>. If the name of your module is "<tt>example</tt>", then the
|
||||
name of the corresponding object file should be
|
||||
"<tt>_example.so</tt>" or "<tt>_examplemodule.so</tt>".
|
||||
The name of the module is specified using the <tt>%module</tt> directive or the
|
||||
The name of the module is specified using the <tt>%module</tt> directive or the
|
||||
<tt>-module</tt> command line option.
|
||||
</p>
|
||||
|
||||
|
|
@ -433,7 +438,7 @@ An alternative approach to dynamic linking is to rebuild the Python
|
|||
interpreter with your extension module added to it. In the past,
|
||||
this approach was sometimes necessary due to limitations in dynamic loading
|
||||
support on certain machines. However, the situation has improved greatly
|
||||
over the last few years and you should not consider this approach
|
||||
over the last few years and you should not consider this approach
|
||||
unless there is really no other option.
|
||||
</p>
|
||||
|
||||
|
|
@ -493,7 +498,7 @@ linking if possible. Some programmers may be inclined
|
|||
to use static linking in the interest of getting better performance.
|
||||
However, the performance gained by static linking tends to be rather
|
||||
minimal in most situations (and quite frankly not worth the extra
|
||||
hassle in the opinion of this author).
|
||||
hassle in the opinion of this author).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -552,13 +557,13 @@ Another possible error is the following:
|
|||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
ImportError: dynamic module does not define init function (init_example)
|
||||
>>>
|
||||
>>>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This error is almost always caused when a bad name is given to the shared object file.
|
||||
For example, if you created a file <tt>example.so</tt> instead of <tt>_example.so</tt> you would
|
||||
This error is almost always caused when a bad name is given to the shared object file.
|
||||
For example, if you created a file <tt>example.so</tt> instead of <tt>_example.so</tt> you would
|
||||
get this error. Alternatively, this error could arise if the name of the module is
|
||||
inconsistent with the module name supplied with the <tt>%module</tt> directive.
|
||||
Double-check the interface to make sure the module name and the shared object
|
||||
|
|
@ -584,7 +589,7 @@ This error usually indicates that you forgot to include some object
|
|||
files or libraries in the linking of the shared library file. Make
|
||||
sure you compile both the SWIG wrapper file and your original program
|
||||
into a shared library file. Make sure you pass all of the required libraries
|
||||
to the linker.
|
||||
to the linker.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -619,7 +624,7 @@ problem when you try to use your module:
|
|||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
ImportError: libfoo.so: cannot open shared object file: No such file or directory
|
||||
>>>
|
||||
>>>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -642,7 +647,7 @@ $ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \
|
|||
|
||||
<p>
|
||||
Alternatively, you can set the <tt>LD_LIBRARY_PATH</tt> environment variable to
|
||||
include the directory with your shared libraries.
|
||||
include the directory with your shared libraries.
|
||||
If setting <tt>LD_LIBRARY_PATH</tt>, be aware that setting this variable can introduce
|
||||
a noticeable performance impact on all other applications that you run.
|
||||
To set it only for Python, you might want to do this instead:
|
||||
|
|
@ -707,7 +712,7 @@ $ CC -G example.o example_wrap.o -L/opt/SUNWspro/lib -o _example.so -lCrun
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
Of course, the extra libraries to use are completely non-portable---you will
|
||||
Of course, the extra libraries to use are completely non-portable---you will
|
||||
probably need to do some experimentation.
|
||||
</p>
|
||||
|
||||
|
|
@ -715,8 +720,8 @@ probably need to do some experimentation.
|
|||
Sometimes people have suggested that it is necessary to relink the
|
||||
Python interpreter using the C++ compiler to make C++ extension modules work.
|
||||
In the experience of this author, this has never actually appeared to be
|
||||
necessary. Relinking the interpreter with C++ really only includes the
|
||||
special run-time libraries described above---as long as you link your extension
|
||||
necessary. Relinking the interpreter with C++ really only includes the
|
||||
special run-time libraries described above---as long as you link your extension
|
||||
modules with these libraries, it should not be necessary to rebuild Python.
|
||||
</p>
|
||||
|
||||
|
|
@ -760,7 +765,7 @@ might want to investigate using a more formal standard such as COM.
|
|||
On platforms that support 64-bit applications (Solaris, Irix, etc.),
|
||||
special care is required when building extension modules. On these
|
||||
machines, 64-bit applications are compiled and linked using a different
|
||||
set of compiler/linker options. In addition, it is not generally possible to mix
|
||||
set of compiler/linker options. In addition, it is not generally possible to mix
|
||||
32-bit and 64-bit code together in the same application.
|
||||
</p>
|
||||
|
||||
|
|
@ -814,10 +819,10 @@ If you need to build it on your own, the following notes are provided:
|
|||
</p>
|
||||
|
||||
<p>
|
||||
You will need to create a DLL that can be loaded into the interpreter.
|
||||
You will need to create a DLL that can be loaded into the interpreter.
|
||||
This section briefly describes the use of SWIG with Microsoft Visual
|
||||
C++. As a starting point, many of SWIG's examples include project
|
||||
files (.dsp files) for Visual C++ 6. These can be opened by more
|
||||
files (.dsp files) for Visual C++ 6. These can be opened by more
|
||||
recent versions of Visual Studio.
|
||||
You might want to take a quick look at these examples in addition to
|
||||
reading this section.
|
||||
|
|
@ -852,7 +857,7 @@ settings, select the "Custom Build" option.
|
|||
"C++:Preprocessor". Add the include directories for your Python
|
||||
installation under "Additional include directories".
|
||||
|
||||
<li>Define the symbol __WIN32__ under preprocessor options.
|
||||
<li>Define the symbol __WIN32__ under preprocessor options.
|
||||
|
||||
<li>Finally, select the settings for the entire project and go to
|
||||
"Link Options". Add the Python library file to your link libraries.
|
||||
|
|
@ -866,7 +871,7 @@ match the name of your Python module, ie. _example.pyd - Note that _example.dll
|
|||
If all went well, SWIG will be automatically invoked whenever
|
||||
you build your project. Any changes made to the interface file will
|
||||
result in SWIG being automatically executed to produce a new version of
|
||||
the wrapper file.
|
||||
the wrapper file.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -885,9 +890,9 @@ $ python
|
|||
<p>
|
||||
If you get an <tt>ImportError</tt> exception when importing the module, you may
|
||||
have forgotten to include additional library files when you built your module.
|
||||
If you get an access violation or some kind of general protection fault
|
||||
immediately upon import, you have a more serious problem. This
|
||||
is often caused by linking your extension module against the wrong
|
||||
If you get an access violation or some kind of general protection fault
|
||||
immediately upon import, you have a more serious problem. This
|
||||
is often caused by linking your extension module against the wrong
|
||||
set of Win32 debug or thread libraries. You will have to fiddle around with
|
||||
the build options of project to try and track this down.
|
||||
</p>
|
||||
|
|
@ -938,7 +943,7 @@ wrapped into a Python '<tt>example</tt>' module. Underneath the covers,
|
|||
this module consists of a Python source file <tt>example.py</tt> and a low-level
|
||||
extension module <tt>_example.so</tt>. When choosing a
|
||||
module name, make sure you don't use the same name as a built-in
|
||||
Python command or standard module name.
|
||||
Python command or standard module name.
|
||||
</p>
|
||||
|
||||
<H3><a name="Python_nn15">36.3.2 Functions</a></H3>
|
||||
|
|
@ -991,8 +996,8 @@ then "a" and "b" are both names for the object containing the value
|
|||
3.4. Thus, there is only one object containing 3.4 and "a"
|
||||
and "b" are both names that refer to it. This is quite
|
||||
different than C where a variable name refers to a memory location in which
|
||||
a value is stored (and assignment copies data into that location).
|
||||
Because of this, there is no direct way to map variable
|
||||
a value is stored (and assignment copies data into that location).
|
||||
Because of this, there is no direct way to map variable
|
||||
assignment in C to variable assignment in Python.
|
||||
</p>
|
||||
|
||||
|
|
@ -1038,7 +1043,7 @@ error message. For example:
|
|||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: C variable 'density (double )'
|
||||
>>>
|
||||
>>>
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -1188,7 +1193,7 @@ simply represented as opaque values using an especial python container object:
|
|||
|
||||
<p>
|
||||
This pointer value can be freely passed around to different C functions that
|
||||
expect to receive an object of type <tt>FILE *</tt>. The only thing you can't do is
|
||||
expect to receive an object of type <tt>FILE *</tt>. The only thing you can't do is
|
||||
dereference the pointer from Python. Of course, that isn't much of a concern in this example.
|
||||
</p>
|
||||
|
||||
|
|
@ -1309,7 +1314,7 @@ is used as follows:
|
|||
>>> v.y = 7.2
|
||||
>>> print v.x, v.y, v.z
|
||||
7.8 -4.5 0.0
|
||||
>>>
|
||||
>>>
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -1368,7 +1373,7 @@ struct Foo {
|
|||
<p>
|
||||
When <tt>char *</tt> members of a structure are wrapped, the contents are assumed to be
|
||||
dynamically allocated using <tt>malloc</tt> or <tt>new</tt> (depending on whether or not
|
||||
SWIG is run with the -c++ option). When the structure member is set, the old contents will be
|
||||
SWIG is run with the -c++ option). When the structure member is set, the old contents will be
|
||||
released and a new value created. If this is not the behavior you want, you will have to use
|
||||
a typemap (described later).
|
||||
</p>
|
||||
|
|
@ -1395,7 +1400,7 @@ If accessed in Python, you will see behavior like this:
|
|||
>>> b = example.Bar()
|
||||
>>> print b.x
|
||||
_801861a4_p_int
|
||||
>>>
|
||||
>>>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -1460,7 +1465,7 @@ Foo *x = &b->f; /* Points inside b */
|
|||
</div>
|
||||
|
||||
<p>
|
||||
Because the pointer points inside the structure, you can modify the contents and
|
||||
Because the pointer points inside the structure, you can modify the contents and
|
||||
everything works just like you would expect. For example:
|
||||
</p>
|
||||
|
||||
|
|
@ -1468,7 +1473,7 @@ everything works just like you would expect. For example:
|
|||
<pre>
|
||||
>>> b = Bar()
|
||||
>>> b.f.a = 3 # Modify attribute of structure member
|
||||
>>> x = b.f
|
||||
>>> x = b.f
|
||||
>>> x.a = 3 # Modifies the same structure
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1510,13 +1515,13 @@ you can use it in Python like this:
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
Class data members are accessed in the same manner as C structures.
|
||||
Class data members are accessed in the same manner as C structures.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Static class members present a special problem for Python. Prior to Python-2.2,
|
||||
Static class members present a special problem for Python. Prior to Python-2.2,
|
||||
Python classes had no support for static methods and no version of Python
|
||||
supports static member variables in a manner that SWIG can utilize. Therefore,
|
||||
supports static member variables in a manner that SWIG can utilize. Therefore,
|
||||
SWIG generates wrappers that try to work around some of these issues. To illustrate,
|
||||
suppose you have a class like this:
|
||||
</p>
|
||||
|
|
@ -1669,10 +1674,10 @@ const Foo &spam9();
|
|||
|
||||
<p>
|
||||
then all three functions will return a pointer to some <tt>Foo</tt> object.
|
||||
Since the third function (spam8) returns a value, newly allocated memory is used
|
||||
to hold the result and a pointer is returned (Python will release this memory
|
||||
Since the third function (spam8) returns a value, newly allocated memory is used
|
||||
to hold the result and a pointer is returned (Python will release this memory
|
||||
when the return value is garbage collected). The fourth case (spam9)
|
||||
which returns a const reference, in most of the cases will be
|
||||
which returns a const reference, in most of the cases will be
|
||||
treated as a returning value, and it will follow the same
|
||||
allocation/deallocation process.
|
||||
</p>
|
||||
|
|
@ -1771,7 +1776,7 @@ To fix this, you either need to ignore or rename one of the methods. For exampl
|
|||
<pre>
|
||||
%rename(spam_short) spam(short);
|
||||
...
|
||||
void spam(int);
|
||||
void spam(int);
|
||||
void spam(short); // Accessed as spam_short
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1784,7 +1789,7 @@ or
|
|||
<pre>
|
||||
%ignore spam(short);
|
||||
...
|
||||
void spam(int);
|
||||
void spam(int);
|
||||
void spam(short); // Ignored
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -1797,7 +1802,7 @@ first declaration takes precedence.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
Please refer to the "SWIG and C++" chapter for more information about overloading.
|
||||
Please refer to the "SWIG and C++" chapter for more information about overloading.
|
||||
</p>
|
||||
|
||||
<H3><a name="Python_nn24">36.3.11 C++ operators</a></H3>
|
||||
|
|
@ -1823,7 +1828,7 @@ public:
|
|||
Complex operator-(const Complex &c) const;
|
||||
Complex operator*(const Complex &c) const;
|
||||
Complex operator-() const;
|
||||
|
||||
|
||||
double re() const { return rpart; }
|
||||
double im() const { return ipart; }
|
||||
};
|
||||
|
|
@ -2005,7 +2010,7 @@ In Python:
|
|||
|
||||
<p>
|
||||
Obviously, there is more to template wrapping than shown in this example.
|
||||
More details can be found in the <a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a> chapter.
|
||||
More details can be found in the <a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a> chapter.
|
||||
Some more complicated
|
||||
examples will appear later.
|
||||
</p>
|
||||
|
|
@ -2188,7 +2193,7 @@ These wrappers can be found in the low-level extension module (e.g., <tt>_exampl
|
|||
</p>
|
||||
|
||||
<p>
|
||||
Using these wrappers, SWIG generates a high-level Python proxy class (also known as a shadow class) like this (shown
|
||||
Using these wrappers, SWIG generates a high-level Python proxy class (also known as a shadow class) like this (shown
|
||||
for Python 2.2):
|
||||
</p>
|
||||
|
||||
|
|
@ -2210,7 +2215,7 @@ class Foo(object):
|
|||
</div>
|
||||
|
||||
<p>
|
||||
This class merely holds a pointer to the underlying C++ object (<tt>.this</tt>) and dispatches methods and
|
||||
This class merely holds a pointer to the underlying C++ object (<tt>.this</tt>) and dispatches methods and
|
||||
member variable access to that object using the low-level accessor functions. From a user's point of
|
||||
view, it makes the class work normally:
|
||||
</p>
|
||||
|
|
@ -2254,7 +2259,7 @@ class Foo(object):
|
|||
</div>
|
||||
|
||||
<p>When a <tt>Foo</tt> instance is created, the call to <tt>_example.new_Foo()</tt>
|
||||
creates a new C++ <tt>Foo</tt> instance; wraps that C++ instance inside an instance of
|
||||
creates a new C++ <tt>Foo</tt> instance; wraps that C++ instance inside an instance of
|
||||
a python built-in type called <tt>SwigPyObject</tt>; and stores the <tt>SwigPyObject</tt>
|
||||
instance in the 'this' field of the python Foo object. Did you get all that? So, the
|
||||
python <tt>Foo</tt> object is composed of three parts:</p>
|
||||
|
|
@ -2545,7 +2550,7 @@ public:
|
|||
</div>
|
||||
|
||||
<p>
|
||||
If you examine the generated code, the supplied hash function will now be
|
||||
If you examine the generated code, the supplied hash function will now be
|
||||
the function callback in the tp_hash slot for the builtin type for <tt>MyClass</tt>:
|
||||
</p>
|
||||
|
||||
|
|
@ -2609,7 +2614,7 @@ when the <tt>-builtin</tt> option is used.</p>
|
|||
<p>
|
||||
Associated with proxy object, is an ownership flag <tt>.thisown</tt> The value of this
|
||||
flag determines who is responsible for deleting the underlying C++ object. If set to 1,
|
||||
the Python interpreter will destroy the C++ object when the proxy class is
|
||||
the Python interpreter will destroy the C++ object when the proxy class is
|
||||
garbage collected. If set to 0 (or if the attribute is missing), then the destruction
|
||||
of the proxy class has no effect on the C++ object.
|
||||
</p>
|
||||
|
|
@ -2712,7 +2717,7 @@ is assigned to a global variable. For example:
|
|||
>>> f = example.Foo()
|
||||
>>> f.thisown
|
||||
1
|
||||
>>> example.cvar.head = f
|
||||
>>> example.cvar.head = f
|
||||
>>> f.thisown
|
||||
0
|
||||
>>>
|
||||
|
|
@ -2813,7 +2818,7 @@ To address differences between Python versions, SWIG currently emits
|
|||
dual-mode proxy class wrappers. In Python-2.2 and newer releases,
|
||||
these wrappers encapsulate C++ objects in new-style classes that take
|
||||
advantage of new features (static methods and properties). However,
|
||||
if these very same wrappers are imported into an older version of Python,
|
||||
if these very same wrappers are imported into an older version of Python,
|
||||
old-style classes are used instead.
|
||||
</p>
|
||||
|
||||
|
|
@ -2883,18 +2888,18 @@ option to the %module directive, like this:
|
|||
|
||||
<p>
|
||||
Without this option no director code will be generated. Second, you
|
||||
must use the %feature("director") directive to tell SWIG which classes
|
||||
and methods should get directors. The %feature directive can be applied
|
||||
must use the %feature("director") directive to tell SWIG which classes
|
||||
and methods should get directors. The %feature directive can be applied
|
||||
globally, to specific classes, and to specific methods, like this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
// generate directors for all classes that have virtual methods
|
||||
%feature("director");
|
||||
%feature("director");
|
||||
|
||||
// generate directors for all virtual methods in class Foo
|
||||
%feature("director") Foo;
|
||||
%feature("director") Foo;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -2912,11 +2917,11 @@ directors for specific classes or methods. So for example,
|
|||
|
||||
<p>
|
||||
will generate directors for all virtual methods of class Foo except
|
||||
bar().
|
||||
bar().
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Directors can also be generated implicitly through inheritance.
|
||||
Directors can also be generated implicitly through inheritance.
|
||||
In the following, class Bar will get a director class that handles
|
||||
the methods one() and two() (but not three()):
|
||||
</p>
|
||||
|
|
@ -2961,9 +2966,6 @@ class MyFoo(mymodule.Foo):
|
|||
<H3><a name="Python_nn34">36.5.2 Director classes</a></H3>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
For each class that has directors enabled, SWIG generates a new class
|
||||
that derives from both the class in question and a special
|
||||
|
|
@ -3224,7 +3226,7 @@ be able to use std::vector, std::string, etc., as you would any other type.
|
|||
|
||||
<p>
|
||||
<b>Note:</b> The director typemaps for return types based in const
|
||||
references, such as
|
||||
references, such as
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
|
|
@ -3498,7 +3500,7 @@ def bar(*args):
|
|||
$action
|
||||
#do something after
|
||||
%}
|
||||
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
int bar(int x);
|
||||
|
|
@ -3507,7 +3509,7 @@ public:
|
|||
</div>
|
||||
|
||||
<p> where <tt>$action</tt> will be replaced by the call to
|
||||
the C/C++ proper method.
|
||||
the C/C++ proper method.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -3525,7 +3527,7 @@ proxy, just before the return statement.
|
|||
<pre>
|
||||
%module example
|
||||
|
||||
// Add python code to bar()
|
||||
// Add python code to bar()
|
||||
|
||||
%feature("pythonprepend") Foo::bar(int) %{
|
||||
#do something before C++ call
|
||||
|
|
@ -3535,7 +3537,7 @@ proxy, just before the return statement.
|
|||
#do something after C++ call
|
||||
%}
|
||||
|
||||
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
int bar(int x);
|
||||
|
|
@ -3554,7 +3556,7 @@ SWIG version 1.3.28 you can use the directive forms
|
|||
<pre>
|
||||
%module example
|
||||
|
||||
// Add python code to bar()
|
||||
// Add python code to bar()
|
||||
|
||||
%pythonprepend Foo::bar(int) %{
|
||||
#do something before C++ call
|
||||
|
|
@ -3564,7 +3566,7 @@ SWIG version 1.3.28 you can use the directive forms
|
|||
#do something after C++ call
|
||||
%}
|
||||
|
||||
|
||||
|
||||
class Foo {
|
||||
public:
|
||||
int bar(int x);
|
||||
|
|
@ -3658,7 +3660,7 @@ Vector(2, 3, 4)
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<tt>%extend</tt> can be used for many more tasks than this.
|
||||
<tt>%extend</tt> can be used for many more tasks than this.
|
||||
For example, if you wanted to overload a Python operator, you might do this:
|
||||
</p>
|
||||
|
||||
|
|
@ -3687,7 +3689,7 @@ Use it like this:
|
|||
>>> w = example.Vector(10, 11, 12)
|
||||
>>> print v+w
|
||||
Vector(12, 14, 16)
|
||||
>>>
|
||||
>>>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -3991,7 +3993,7 @@ int send_message(char *text, int *success);
|
|||
</div>
|
||||
|
||||
<p>
|
||||
When used in Python, the function will return multiple values.
|
||||
When used in Python, the function will return multiple values.
|
||||
</p>
|
||||
|
||||
<div class="targetlang">
|
||||
|
|
@ -4142,7 +4144,7 @@ int sumitems(int *first, int nitems) {
|
|||
</div>
|
||||
|
||||
<p>
|
||||
To wrap this into Python, you need to pass an array pointer as the first argument.
|
||||
To wrap this into Python, you need to pass an array pointer as the first argument.
|
||||
A simple way to do this is to use the <tt>carrays.i</tt> library file. For example:
|
||||
</p>
|
||||
|
||||
|
|
@ -4219,13 +4221,13 @@ using the <tt>cstring.i</tt> library file described in the <a href="Library.html
|
|||
</p>
|
||||
|
||||
<p>
|
||||
When functions return a <tt>char *</tt>, it is assumed to be a NULL-terminated string.
|
||||
When functions return a <tt>char *</tt>, it is assumed to be a NULL-terminated string.
|
||||
Data is copied into a new Python string and returned.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If your program needs to work with binary data, you can use a typemap
|
||||
to expand a Python string into a pointer/length argument pair. As luck would have it,
|
||||
to expand a Python string into a pointer/length argument pair. As luck would have it,
|
||||
just such a typemap is already defined. Just do this:
|
||||
</p>
|
||||
|
||||
|
|
@ -4260,7 +4262,7 @@ also be used to extra binary data from arbitrary pointers.
|
|||
<p>
|
||||
C++ default argument code generation is documented in the main
|
||||
<a href="SWIGPlus.html#SWIGPlus_default_args">Default arguments</a> section.
|
||||
There is also an optional Python specific feature that can be used called the <tt>python:cdefaultargs</tt>
|
||||
There is also an optional Python specific feature that can be used called the <tt>python:cdefaultargs</tt>
|
||||
<a href="Customization.html#Customization_feature_flags">feature flag</a>.
|
||||
By default, SWIG attempts to convert C++ default argument values
|
||||
into Python values and generates code into the Python layer containing these values.
|
||||
|
|
@ -4303,7 +4305,7 @@ class CDA(object):
|
|||
<p>
|
||||
Adding the feature:
|
||||
</p>
|
||||
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%feature("python:cdefaultargs") CDA::fff;
|
||||
|
|
@ -4364,7 +4366,7 @@ as the material in the "<a href="Typemaps.html#Typemaps">Typemaps</a>" chapter.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
Before proceeding, it should be stressed that typemaps are not a required
|
||||
Before proceeding, it should be stressed that typemaps are not a required
|
||||
part of using SWIG---the default wrapping behavior is enough in most cases.
|
||||
Typemaps are only used if you want to change some aspect of the primitive
|
||||
C-Python interface or if you want to elevate your guru status.
|
||||
|
|
@ -4374,7 +4376,7 @@ C-Python interface or if you want to elevate your guru status.
|
|||
|
||||
|
||||
<p>
|
||||
A typemap is nothing more than a code generation rule that is attached to
|
||||
A typemap is nothing more than a code generation rule that is attached to
|
||||
a specific C datatype. For example, to convert integers from Python to C,
|
||||
you might define a typemap like this:
|
||||
</p>
|
||||
|
|
@ -4506,7 +4508,7 @@ like this:
|
|||
|
||||
<p>
|
||||
A detailed list of available methods can be found in the "<a
|
||||
href="Typemaps.html#Typemaps">Typemaps</a>" chapter.
|
||||
href="Typemaps.html#Typemaps">Typemaps</a>" chapter.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -4568,7 +4570,7 @@ A <tt>PyObject *</tt> that holds the result to be returned to Python.
|
|||
</p>
|
||||
|
||||
<div class="indent">
|
||||
The parameter name that was matched.
|
||||
The parameter name that was matched.
|
||||
</div>
|
||||
|
||||
<p>
|
||||
|
|
@ -4812,7 +4814,7 @@ In the example, two different typemaps are used. The "in" typemap is
|
|||
used to receive an input argument and convert it to a C array. Since dynamic
|
||||
memory allocation is used to allocate memory for the array, the
|
||||
"freearg" typemap is used to later release this memory after the execution of
|
||||
the C function.
|
||||
the C function.
|
||||
</p>
|
||||
|
||||
<H3><a name="Python_nn60">36.9.2 Expanding a Python object into multiple arguments</a></H3>
|
||||
|
|
@ -4878,7 +4880,7 @@ previous example:
|
|||
</div>
|
||||
|
||||
<p>
|
||||
When writing a multiple-argument typemap, each of the types is referenced by a variable such
|
||||
When writing a multiple-argument typemap, each of the types is referenced by a variable such
|
||||
as <tt>$1</tt> or <tt>$2</tt>. The typemap code simply fills in the appropriate values from
|
||||
the supplied Python object.
|
||||
</p>
|
||||
|
|
@ -4960,7 +4962,7 @@ A typemap can be used to handle this case as follows :
|
|||
%module outarg
|
||||
|
||||
// This tells SWIG to treat an double * argument with name 'OutValue' as
|
||||
// an output value. We'll append the value to the current result which
|
||||
// an output value. We'll append the value to the current result which
|
||||
// is guaranteed to be a List object by SWIG.
|
||||
|
||||
%typemap(argout) double *OutValue {
|
||||
|
|
@ -5312,7 +5314,7 @@ example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%define DOCSTRING
|
||||
"The `XmlResource` class allows program resources defining menus,
|
||||
"The `XmlResource` class allows program resources defining menus,
|
||||
layout of controls on a panel, etc. to be loaded from an XML file."
|
||||
%enddef
|
||||
|
||||
|
|
@ -5607,7 +5609,7 @@ Packages</a> for more information.
|
|||
|
||||
<p>
|
||||
If you place a SWIG generated module into a Python package then there
|
||||
are details concerning the way SWIG
|
||||
are details concerning the way SWIG
|
||||
<a href="#Python_package_search">searches for the wrapper module</a>
|
||||
that you may want to familiarize yourself with.
|
||||
</p>
|
||||
|
|
@ -6378,7 +6380,7 @@ In Python:
|
|||
>>> snprintf(buf, "Hello world!")
|
||||
>>> print(buf)
|
||||
bytearray(b'Hello\x00')
|
||||
>>>
|
||||
>>>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
|
@ -6414,7 +6416,7 @@ bytearray(b'FOO\x00')
|
|||
|
||||
<p>
|
||||
Both <tt>%pybuffer_mutable_binary</tt> and <tt>%pybuffer_mutable_string</tt>
|
||||
require the provided buffer to be mutable, eg. they can accept a
|
||||
require the provided buffer to be mutable, eg. they can accept a
|
||||
<tt>bytearray</tt> type but can't accept an immutable <tt>byte</tt>
|
||||
type.
|
||||
</p>
|
||||
|
|
@ -6730,6 +6732,110 @@ the first is allowing unicode conversion and the second is explicitly
|
|||
prohibiting it.
|
||||
</p>
|
||||
|
||||
<H2><a name="Python_multithreaded">36.13 Support for Multithreaded Applications</a></H2>
|
||||
|
||||
|
||||
<p>By default, SWIG does not enable support for multithreaded Python applications. More
|
||||
specifically, the Python wrappers generated by SWIG will not release the
|
||||
Python's interpreter's Global Interpreter Lock (GIL) when wrapped C/C++ code is
|
||||
entered. Hence, while any of the wrapped C/C++ code is executing, the Python interpreter
|
||||
will not be able to run any other threads, even if the wrapped C/C++ code is waiting
|
||||
in a blocking call for something like network or disk IO.
|
||||
|
||||
Fortunately, SWIG does have the ability to enable multithreaded support and automatic
|
||||
release of the GIL either for all wrapped code in a module or on a more selective basis. The user
|
||||
interface for this is described in the next section.
|
||||
</p>
|
||||
|
||||
<H3><a name="Python_thread_UI">36.13.1 UI for Enabling Multithreading Support</a></H3>
|
||||
|
||||
|
||||
<p>The user interface is as follows:</p>
|
||||
<ol>
|
||||
<li><p>Module thread support can be enabled in two ways:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p>
|
||||
The <tt>-threads</tt> swig python option at the command line (or in <tt>setup.py</tt>):
|
||||
</p>
|
||||
<div class="shell"><pre>$ swig -python -threads example.i</pre></div>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
The <tt>threads</tt> module option in the *.i template file:
|
||||
</p>
|
||||
<div class="code"><pre>%feature("nothread") method;</pre></div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p>You can disable thread support for a given method:</p>
|
||||
<div class="code"><pre>%module("threads"=1)</pre></div>
|
||||
or
|
||||
<div class="code"><pre>%nothread method;</pre></div>
|
||||
</li>
|
||||
<li><p>You can partially disable thread support for a given method:</p>
|
||||
<ul>
|
||||
<li><p>To disable the C++/python thread protection:</p>
|
||||
<div class="code"><pre>%feature("nothreadblock") method;</pre></div>
|
||||
or
|
||||
<div class="code"><pre>%nothreadblock method;</pre></div>
|
||||
</li>
|
||||
<li>
|
||||
<p>To disable the python/C++ thread protection</p>
|
||||
<div class="code"><pre>%feature("nothreadallow") method;</pre></div>
|
||||
or
|
||||
<div class="code"><pre>%nothreadallow method;</pre></div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<H3><a name="Python_thread_performance">36.13.2 Multithread Performance</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
For the curious about performance, here are some numbers for the profiletest.i test,
|
||||
which is used to check the speed of the wrapped code:
|
||||
</p>
|
||||
|
||||
<table summary="Python multithread performance">
|
||||
<tr>
|
||||
<th>Thread Mode</th>
|
||||
<th>Execution Time (sec)</th>
|
||||
<th>Comment</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Single Threaded</td>
|
||||
<td>9.6</td>
|
||||
<td>no "-threads" option given</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Fully Multithreaded</td>
|
||||
<td>15.5</td>
|
||||
<td>"-threads" option = 'allow' + 'block'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>No Thread block</td>
|
||||
<td>12.2</td>
|
||||
<td>only 'allow'</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>No Thread Allow</td>
|
||||
<td>13.6</td>
|
||||
<td>only block'</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
Fullly threaded code decreases the wrapping performance by
|
||||
around 60%. If that is important to your application, you
|
||||
can tune each method using the different 'nothread',
|
||||
'nothreadblock' or 'nothreadallow' features as
|
||||
needed. Note that for some methods deactivating the
|
||||
'thread block' or 'thread allow' code is not an option,
|
||||
so, be careful.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue