From a1ff35769b9fe0b5bc11ac563b90ebce83e72710 Mon Sep 17 00:00:00 2001 From: Joel de Guzman Date: Tue, 14 Feb 2006 02:24:32 +0000 Subject: [PATCH] Doc Tweaks [SVN r32910] --- doc/tutorial/doc/html/index.html | 30 ++--- doc/tutorial/doc/html/python/embedding.html | 83 +++++++------- doc/tutorial/doc/html/python/exception.html | 9 +- doc/tutorial/doc/html/python/exposing.html | 109 ++++++++++--------- doc/tutorial/doc/html/python/functions.html | 75 +++++++------ doc/tutorial/doc/html/python/hello.html | 55 ++++++---- doc/tutorial/doc/html/python/iterators.html | 44 +++++--- doc/tutorial/doc/html/python/object.html | 84 +++++++------- doc/tutorial/doc/html/python/techniques.html | 71 ++++++------ doc/tutorial/doc/tutorial.qbk | 7 +- 10 files changed, 309 insertions(+), 258 deletions(-) diff --git a/doc/tutorial/doc/html/index.html b/doc/tutorial/doc/html/index.html index 4929ad50..9a25b848 100644 --- a/doc/tutorial/doc/html/index.html +++ b/doc/tutorial/doc/html/index.html @@ -9,7 +9,7 @@ - + @@ -31,7 +31,7 @@
-

+

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt ) @@ -83,18 +83,18 @@

QuickStart

- QuickStartThe Boost Python Library is a framework for interfacing Python and - C++. It allows you to quickly and seamlessly expose C++ classes functions and - objects to Python, and vice-versa, using no special tools -- just your C++ - compiler. It is designed to wrap C++ interfaces non-intrusively, so that you - should not have to change the C++ code at all in order to wrap it, making Boost.Python + The Boost Python Library is a framework for interfacing Python and C++. It + allows you to quickly and seamlessly expose C++ classes functions and objects + to Python, and vice-versa, using no special tools -- just your C++ compiler. + It is designed to wrap C++ interfaces non-intrusively, so that you should not + have to change the C++ code at all in order to wrap it, making Boost.Python ideal for exposing 3rd-party libraries to Python. The library's use of advanced metaprogramming techniques simplifies its syntax for users, so that wrapping code takes on the look of a kind of declarative interface definition language (IDL).

- + Hello World

@@ -123,19 +123,23 @@ That's it. We're done. We can now build this as a shared library. The resulting DLL is now visible to Python. Here's a sample Python session:

-

+

+

 >>> import hello
 >>> print hello.greet()
 hello, world
 
-

-

Next stop... Building your Hello World module - from start to finish...

+

+

+

+ Next stop... Building your Hello World module + from start to finish... +

boost.png (6897 bytes)Boost C++ Libraries Home Libraries People
- +

Last revised: October 31, 2005 at 18:46:06 GMT

Last revised: February 14, 2006 at 02:23:06 GMT


diff --git a/doc/tutorial/doc/html/python/embedding.html b/doc/tutorial/doc/html/python/embedding.html index fa6cce61..26eaff1e 100644 --- a/doc/tutorial/doc/html/python/embedding.html +++ b/doc/tutorial/doc/html/python/embedding.html @@ -11,7 +11,7 @@ - + @@ -27,19 +27,20 @@ Embedding
Using the interpreter

- EmbeddingBy now you should know how to use Boost.Python to call your C++ code - from Python. However, sometimes you may need to do the reverse: call Python - code from the C++-side. This requires you to embed the - Python interpreter into your C++ program. + By now you should know how to use Boost.Python to call your C++ code from Python. + However, sometimes you may need to do the reverse: call Python code from the + C++-side. This requires you to embed the Python interpreter + into your C++ program.

Currently, Boost.Python does not directly support everything you'll need when embedding. Therefore you'll need to use the Python/C API to fill in the gaps. However, Boost.Python already makes embedding a lot easier and, in a future version, it may become unnecessary to touch the - Python/C API at all. So stay tuned...

+ Python/C API at all. So stay tuned... smiley +

- + Building embedded programs

@@ -83,7 +84,7 @@ exe embedded_program # name of the executable <find-library>$(PYTHON_EMBEDDED_LIBRARY) ;

- + Getting started

@@ -92,7 +93,9 @@ exe embedded_program # name of the executable

  1. - #include <boost/python.hpp>

    + +#include +  <boost/python.hpp>

  2. Call Py_Initialize() @@ -110,24 +113,25 @@ exe embedded_program # name of the executable

    (Of course, there can be other C++ code between all of these steps.)

    -

    Now that we can embed the interpreter in - our programs, lets see how to put it to use...

    +

    + Now that we can embed the interpreter in + our programs, lets see how to put it to use... +

    Using the interpreter

    - Using the interpreterAs you probably already know, objects in Python are - reference-counted. Naturally, the PyObjects of the Python/C - API are also reference-counted. There is a difference however. While the - reference-counting is fully automatic in Python, the Python/C API requires - you to do it by + As you probably already know, objects in Python are reference-counted. Naturally, + the PyObjects of the Python/C API are also reference-counted. + There is a difference however. While the reference-counting is fully automatic + in Python, the Python/C API requires you to do it by hand. This is messy and especially hard to get right in the presence of C++ exceptions. Fortunately Boost.Python provides the handle and object class templates to automate the process.

    - + Reference-counting handles and objects

    @@ -163,17 +167,18 @@ exe embedded_program # name of the executable

boost.png (6897 bytes)Boost C++ Libraries Home Libraries People
-
- Handle is a class template, so why - haven't we been using any template parameters?

handle has a single template parameter specifying - the type of the managed object. This type is PyObject - 99% of the time, so the parameter was defaulted to PyObject - for convenience. Therefore we can use the shorthand handle<> - instead of the longer, but equivalent, handle<PyObject>. +
note Handle is a class + template, so why haven't we been using any template + parameters?

handle has a + single template parameter specifying the type of the managed object. + This type is PyObject 99% of the time, so the parameter + was defaulted to PyObject for convenience. Therefore + we can use the shorthand handle<> instead + of the longer, but equivalent, handle<PyObject>.

- + Running Python code

@@ -184,7 +189,8 @@ exe embedded_program # name of the executable

 PyObject* PyRun_String(char *str, int start, PyObject *globals, PyObject *locals)
 
-

PyRun_String +

+ PyRun_String takes the code to execute as a null-terminated (C-style) string in its str parameter. The function returns a new reference to a Python object. Which object is returned depends on the start paramater. @@ -195,8 +201,9 @@ exe embedded_program # name of the executable

-Start symbols -

+ + Start symbols + @@ -269,8 +276,8 @@ exe embedded_program # name of the executable

-
- Note that we wrap the return value of PyRun_String +
note Note that + we wrap the return value of PyRun_String in a (nameless) handle even though we are not interested in it. If we didn't do this, the the returned object would be kept alive unnecessarily. Unless you want to be a Dr. Frankenstein, always @@ -278,7 +285,7 @@ exe embedded_program # name of the executable

- + Beyond handles

@@ -326,15 +333,15 @@ exe embedded_program # name of the executable

- +
- Note that object's member - function to return the wrapped PyObject* is called - ptr instead of get. This makes - sense if you take into account the different functions that object - and handle perform.
note Note that + object's member function to return the wrapped + PyObject* is called ptr instead + of get. This makes sense if you take into account + the different functions that object and handle + perform.

- + Exception handling

diff --git a/doc/tutorial/doc/html/python/exception.html b/doc/tutorial/doc/html/python/exception.html index cc6d632e..d443959b 100644 --- a/doc/tutorial/doc/html/python/exception.html +++ b/doc/tutorial/doc/html/python/exception.html @@ -11,7 +11,7 @@ - + @@ -26,10 +26,9 @@

Exception Translation

- Exception TranslationAll C++ exceptions must be caught at the boundary with - Python code. This boundary is the point where C++ meets Python. Boost.Python - provides a default exception handler that translates selected standard exceptions, - then gives up: + All C++ exceptions must be caught at the boundary with Python code. This boundary + is the point where C++ meets Python. Boost.Python provides a default exception + handler that translates selected standard exceptions, then gives up:

 raise RuntimeError, 'unidentifiable C++ Exception'
diff --git a/doc/tutorial/doc/html/python/exposing.html b/doc/tutorial/doc/html/python/exposing.html
index 4959c175..fa5c1096 100644
--- a/doc/tutorial/doc/html/python/exposing.html
+++ b/doc/tutorial/doc/html/python/exposing.html
@@ -11,7 +11,7 @@
 
 
 
boost.png (6897 bytes)Boost C++ Libraries Home Libraries People
- + @@ -35,7 +35,7 @@
Class Operators/Special Functions

- Exposing ClassesNow let's expose a C++ class to Python. + Now let's expose a C++ class to Python.

Consider a C++ class/struct that we want to expose to Python: @@ -69,7 +69,8 @@ we may use our class World in Python. Here's a sample Python session:

-

+

+

 >>> import hello
 >>> planet = hello.World()
@@ -81,10 +82,10 @@
 

Constructors

- ConstructorsOur previous example didn't have any explicit constructors. Since - World is declared as a plain struct, it has an implicit - default constructor. Boost.Python exposes the default constructor by default, - which is why we were able to write + Our previous example didn't have any explicit constructors. Since World + is declared as a plain struct, it has an implicit default constructor. Boost.Python + exposes the default constructor by default, which is why we were able to + write

 >>> planet = hello.World()
@@ -93,7 +94,8 @@
         We may wish to wrap a class with a non-default constructor. Let us build
         on our previous example:
       

-

+

+

 struct World
 {
@@ -121,7 +123,8 @@
     ;
 }
 
-

init<std::string>() exposes the constructor taking +

+ init<std::string>() exposes the constructor taking in a std::string (in Python, constructors are spelled ""_init_"").

@@ -153,9 +156,9 @@

Class Data Members

- Class Data MembersData members may also be exposed to Python so that they - can be accessed as attributes of the corresponding Python class. Each data - member that we wish to be exposed may be regarded as read-only + Data members may also be exposed to Python so that they can be accessed as + attributes of the corresponding Python class. Each data member that we wish + to be exposed may be regarded as read-only or read-write. Consider this class Var:

@@ -179,7 +182,8 @@
         Then, in Python, assuming we have placed our Var class inside the namespace
         hello as we did before:
       

-

+

+

 >>> x = hello.Var('pi')
 >>> x.value = 3.14
@@ -201,13 +205,13 @@
 

Class Properties

- Class PropertiesIn C++, classes with public data members are usually frowned - upon. Well designed classes that take advantage of encapsulation hide the - class' data members. The only way to access the class' data is through access - (getter/setter) functions. Access functions expose class properties. Here's - an example: + In C++, classes with public data members are usually frowned upon. Well designed + classes that take advantage of encapsulation hide the class' data members. + The only way to access the class' data is through access (getter/setter) + functions. Access functions expose class properties. Here's an example: +

+

-

 struct Num
 {
@@ -231,7 +235,8 @@
 

And at last, in Python:

-

+

+

 >>> x = Num()
 >>> x.value = 3.14
@@ -244,7 +249,8 @@
         read-only since the rovalue
         setter member function is not passed in:
       

-

+

+

 .add_property("rovalue", &Num::get)
 
@@ -253,7 +259,7 @@

Inheritance

- InheritanceIn the previous examples, we dealt with classes that are not polymorphic. + In the previous examples, we dealt with classes that are not polymorphic. This is not often the case. Much of the time, we will be wrapping polymorphic classes and class hierarchies related by inheritance. We will often have to write Boost.Python wrappers for classes that are derived from abstract @@ -335,9 +341,9 @@

Class Virtual Functions

- Class Virtual FunctionsIn this section, we shall learn how to make functions - behave polymorphically through virtual functions. Continuing our example, - let us add a virtual function to our Base class: + In this section, we shall learn how to make functions behave polymorphically + through virtual functions. Continuing our example, let us add a virtual function + to our Base class:

 struct Base
@@ -375,10 +381,10 @@
       

boost.png (6897 bytes)Boost C++ Libraries Home Libraries People
- +
- MSVC6/7 Workaround

If you are using - Microsoft Visual C++ 6 or 7, you have to write f - as:

return call<int>(this->get_override("f").ptr());.
alert MSVC6/7 Workaround
+
If you are using Microsoft Visual C++ 6 or 7, you have to write + f as:

+ return call<int>(this->get_override("f").ptr());.

BaseWrap's overridden virtual member function f @@ -392,16 +398,17 @@ .def("f", pure_virtual(&Base::f)) ; -

pure_virtual signals Boost.Python +

+ pure_virtual signals Boost.Python that the function f is a pure virtual function.

-
- member function and methods

Python, - like many object oriented languages uses the term methods. - Methods correspond roughly to C++'s member functions +
note member function and + methods

Python, like many object oriented languages + uses the term methods. Methods correspond + roughly to C++'s member functions
@@ -409,11 +416,10 @@

Virtual Functions with Default Implementations

- Virtual Functions with Default ImplementationsWe've seen in the previous - section how classes with pure virtual functions are wrapped using Boost.Python's - class wrapper facilities. If - we wish to wrap non-pure-virtual functions - instead, the mechanism is a bit different. + We've seen in the previous section how classes with pure virtual functions + are wrapped using Boost.Python's class + wrapper facilities. If we wish to wrap non-pure-virtual + functions instead, the mechanism is a bit different.

Recall that in the previous @@ -460,10 +466,9 @@

- +
- MSVC6/7 Workaround

If you are using - Microsoft Visual C++ 6 or 7, you have to rewrite the line with the - *note* as:

return call<char const*>(f.ptr());.
alert MSVC6/7 Workaround
+
If you are using Microsoft Visual C++ 6 or 7, you have to rewrite + the line with the *note* as:

return call<char const*>(f.ptr());.

Finally, exposing: @@ -482,7 +487,8 @@

In Python, the results would be as expected:

-

+

+

 >>> base = Base()
 >>> class Derived(Base):
@@ -509,9 +515,9 @@
 

Class Operators/Special Functions

-

- - Class Operators/Special FunctionsPython Operators +

+ + Python Operators

C is well known for the abundance of operators. C++ extends this to the extremes @@ -522,7 +528,8 @@ Consider a file position class FilePos and a set of operators that take on FilePos instances:

-

+

+

 class FilePos { /*...*/ };
 
@@ -558,7 +565,7 @@
         expressions".
       

- + Special Methods

@@ -588,9 +595,7 @@

-
- - What is the business of operator<<? Well, the method str requires the operator<< to do its work (i.e. operator<< +
note What is the business of operator<<? Well, the method str requires the operator<< to do its work (i.e. operator<< is used by the method defined by def(str(self)).
diff --git a/doc/tutorial/doc/html/python/functions.html b/doc/tutorial/doc/html/python/functions.html index 7070ccfe..81bf8263 100644 --- a/doc/tutorial/doc/html/python/functions.html +++ b/doc/tutorial/doc/html/python/functions.html @@ -11,7 +11,7 @@ - + @@ -32,13 +32,15 @@
Auto-Overloading

- FunctionsIn this chapter, we'll look at Boost.Python powered functions in closer - detail. We shall see some facilities to make exposing C++ functions to Python - safe from potential pifalls such as dangling pointers and references. We shall - also see facilities that will make it even easier for us to expose C++ functions + In this chapter, we'll look at Boost.Python powered functions in closer detail. + We shall see some facilities to make exposing C++ functions to Python safe + from potential pifalls such as dangling pointers and references. We shall also + see facilities that will make it even easier for us to expose C++ functions that take advantage of C++ features such as overloading and default arguments.

-

Read on...

+

+ Read on... +

But before you do, you might want to fire up Python 2.2 or later and type >>> import this. @@ -69,15 +71,15 @@ Namespaces are one honking great idea -- let's do more of those!

Call Policies

- Call PoliciesIn C++, we often deal with arguments and return types such as - pointers and references. Such primitive types are rather, ummmm, low level - and they really don't tell us much. At the very least, we don't know the - owner of the pointer or the referenced object. No wonder languages such as - Java and Python never deal with such low level entities. In C++, it's usually - considered a good practice to use smart pointers which exactly describe ownership - semantics. Still, even good C++ interfaces use raw references and pointers - sometimes, so Boost.Python must deal with them. To do this, it may need your - help. Consider the following C++ function: + In C++, we often deal with arguments and return types such as pointers and + references. Such primitive types are rather, ummmm, low level and they really + don't tell us much. At the very least, we don't know the owner of the pointer + or the referenced object. No wonder languages such as Java and Python never + deal with such low level entities. In C++, it's usually considered a good + practice to use smart pointers which exactly describe ownership semantics. + Still, even good C++ interfaces use raw references and pointers sometimes, + so Boost.Python must deal with them. To do this, it may need your help. Consider + the following C++ function:

 X& f(Y& y, Z* z);
@@ -135,7 +137,8 @@ Namespaces are one honking great idea -- let's do more of those!
 

We could copy result into a new object:

-

+

+

 >>> f(y, z).set(42) # Result disappears
 >>> y.x.get()       # No crash, but still bad
@@ -149,7 +152,8 @@ Namespaces are one honking great idea -- let's do more of those!
 

Our problems do not end there. Suppose Y is implemented as follows:

-

+

+

 struct Y
 {
@@ -202,7 +206,7 @@ Namespaces are one honking great idea -- let's do more of those!
 
  • BOOM!
  • - + Call Policies

    @@ -285,20 +289,19 @@ Namespaces are one honking great idea -- let's do more of those!

    boost.png (6897 bytes)Boost C++ Libraries Home Libraries People
    - +
    - Remember the Zen, Luke:

    "Explicit - is better than implicit"
    "In the face of ambiguity, - refuse the temptation to guess"
    -
    smiley Remember the Zen, Luke:
    +
    "Explicit is better than implicit"
    "In + the face of ambiguity, refuse the temptation to guess"
    +

    Overloading

    - OverloadingThe following illustrates a scheme for manually wrapping an overloaded - member functions. Of course, the same technique can be applied to wrapping - overloaded non-member functions. + The following illustrates a scheme for manually wrapping an overloaded member + functions. Of course, the same technique can be applied to wrapping overloaded + non-member functions.

    We have here our C++ class: @@ -351,8 +354,8 @@ Namespaces are one honking great idea -- let's do more of those!

    Default Arguments

    - Default ArgumentsBoost.Python wraps (member) function pointers. Unfortunately, - C++ function pointers carry no default argument info. Take a function f + Boost.Python wraps (member) function pointers. Unfortunately, C++ function + pointers carry no default argument info. Take a function f with default arguments:

    @@ -401,7 +404,7 @@ Namespaces are one honking great idea -- let's do more of those!
             
     

    - + BOOST_PYTHON_FUNCTION_OVERLOADS

    @@ -431,7 +434,7 @@ Namespaces are one honking great idea -- let's do more of those! def("foo", foo, foo_overloads());

    - + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS

    @@ -477,7 +480,7 @@ Namespaces are one honking great idea -- let's do more of those! reference for details.

    - + init and optional

    @@ -507,10 +510,10 @@ Namespaces are one honking great idea -- let's do more of those!

    Auto-Overloading

    - Auto-OverloadingIt was mentioned in passing in the previous section that - BOOST_PYTHON_FUNCTION_OVERLOADS and BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS - can also be used for overloaded functions and member functions with a common - sequence of initial arguments. Here is an example: + It was mentioned in passing in the previous section that BOOST_PYTHON_FUNCTION_OVERLOADS + and BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS can also be + used for overloaded functions and member functions with a common sequence + of initial arguments. Here is an example:

     void foo()
    @@ -551,7 +554,7 @@ Namespaces are one honking great idea -- let's do more of those!
             (0) arguments and a maximum of 3 arguments.
           

    - + Manual Wrapping

    diff --git a/doc/tutorial/doc/html/python/hello.html b/doc/tutorial/doc/html/python/hello.html index 6d648bf9..fe93c26b 100644 --- a/doc/tutorial/doc/html/python/hello.html +++ b/doc/tutorial/doc/html/python/hello.html @@ -11,7 +11,7 @@ - + @@ -25,9 +25,9 @@

    Building Hello World

    -

    - - Building Hello WorldFrom Start To Finish +

    + + From Start To Finish

    Now the first thing you'd want to do is to build the Hello World module and @@ -37,11 +37,11 @@

    boost.png (6897 bytes)Boost C++ Libraries Home Libraries People
    - @@ -99,10 +99,12 @@ platforms. The complete list of Bjam executables can be found here.

    - + Let's Jam!

    -

    +

    + jam +

    Here is our minimalist Jamfile:

    @@ -148,10 +150,11 @@ extension hello # Declare a Python extension called hello The last part tells BJam that we are depending on the Boost Python Library.

    - + Running bjam

    -

    bjam is run using your operating system's command line +

    + bjam is run using your operating system's command line interpreter.

    @@ -177,10 +180,8 @@ set PYTHON_VERSION=2.2

    - Building without bjam

    Besides bjam, - there are of course other ways to get your module built. What's written - here should not be taken as "the one and only way". There are - of course other build tools apart from bjam.

    Take note however that the preferred build tool for Boost.Python +
    note Building without bjam
    +
    Besides bjam, there are of course other ways to get your module + built. What's written here should not be taken as "the one and only + way". There are of course other build tools apart from bjam.
    +
    Take note however that the preferred build tool for Boost.Python is bjam. There are so many ways to set up the build incorrectly. Experience shows that 90% of the "I can't build Boost.Python" problems come from people who had to use a different tool.
    - +
    - - Be sure not to include a third number, e.g. not - "2.2.1", even if that's the version you have.
    tip Be sure not to include a third number, e.g. not "2.2.1", even if that's the version + you have.

    Take note that you may also do that through the Jamrules file we put in our @@ -251,23 +252,29 @@ b and object bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.exp

    if you are on Unix.

    -

    boost_python.dll and hello.pyd can be +

    + boost_python.dll and hello.pyd can be found somewhere in your project's bin directory. After a - successful build, you can just link in these DLLs with the Python interpreter. - In Windows for example, you can simply put these libraries inside the directory - where the Python executable is. + successful build, you make it possible for the system to find boost_python.dll + or libboost_python.so (usually done with LD_LIBRARY_PATH, DYLD_LIBRARY_PATH, + or some other variable on *nix and with PATH on Windows) and for Python to + find the hello module (Done with PYTHONPATH on all systems.)

    You may now fire up Python and run our hello module:

    -

    +

    +

     >>> import hello
     >>> print hello.greet()
     hello, world
     
    -

    -

    There you go... Have fun!

    +

    +

    +

    + There you go... Have fun! +

    diff --git a/doc/tutorial/doc/html/python/iterators.html b/doc/tutorial/doc/html/python/iterators.html index 022620e1..4abaa075 100644 --- a/doc/tutorial/doc/html/python/iterators.html +++ b/doc/tutorial/doc/html/python/iterators.html @@ -11,7 +11,7 @@
    - + @@ -26,10 +26,12 @@

    Iterators

    - IteratorsIn C++, and STL in particular, we see iterators everywhere. Python - also has iterators, but these are two very different beasts. + In C++, and STL in particular, we see iterators everywhere. Python also has + iterators, but these are two very different beasts. +

    +

    + C++ iterators:

    -

    C++ iterators:

    • C++ has 5 type categories (random-access, bidirectional, forward, input, @@ -42,7 +44,9 @@ A pair of iterators is needed to represent a (first/last) range.
    -

    Python Iterators:

    +

    + Python Iterators: +

    • 1 category (forward) @@ -58,7 +62,8 @@ The typical Python iteration protocol: for y in x... is as follows:

      -

      +

      +

       iter = x.__iter__()         # get iterator
       try:
      @@ -72,7 +77,8 @@
             as Python iterators. What we need to do is to produce appropriate __iter__ function from C++ iterators that
             is compatible with the Python iteration protocol. For example:
           

      -

      +

      +

       object get_iterator = iterator<vector<int> >();
       object iter = get_iterator(v);
      @@ -84,7 +90,9 @@
       
       .def("__iter__", iterator<vector<int> >())
       
      -

      range

      +

      + range +

      We can create a Python savvy iterator using the range function:

      @@ -110,7 +118,9 @@ adaptable function object (use Target parameter)
    -

    iterator

    +

    + iterator +

    • iterator<T, Policies>()
    @@ -122,7 +132,8 @@ Let's put this into action... Here's an example from some hypothetical bogon Particle accelerator code:

    -

    +

    +

     f = Field()
     for x in f.pions:
    @@ -133,13 +144,16 @@
     

    Now, our C++ Wrapper:

    -

    +

    +

     class_<F>("Field")
         .property("pions", range(&F::p_begin, &F::p_end))
         .property("bogons", range(&F::b_begin, &F::b_end));
     
    -

    stl_input_iterator

    +

    + stl_input_iterator +

    So far, we have seen how to expose C++ iterators and ranges to Python. Sometimes we wish to go the other way, though: we'd like to pass a Python sequence to @@ -147,7 +161,8 @@ a Python iterator look like an STL iterator. For that, we use stl_input_iterator<>. Consider how we might implement a function that exposes std::list<int>::assign() to Python:

    -

    +

    +

     template<typename T>
     void list_assign(std::list<T>& l, object o) {
    @@ -166,7 +181,8 @@
           Now in Python, we can assign any integer sequence to list_int
           objects:
         

    -

    +

    +

     x = list_int();
     x.assign([1,2,3,4,5])
    diff --git a/doc/tutorial/doc/html/python/object.html b/doc/tutorial/doc/html/python/object.html
    index e17cf4a4..50a11036 100644
    --- a/doc/tutorial/doc/html/python/object.html
    +++ b/doc/tutorial/doc/html/python/object.html
    @@ -11,7 +11,7 @@
     
     
     
    boost.png (6897 bytes)Boost C++ Libraries Home Libraries People
    - + @@ -32,11 +32,11 @@
    Enums

    - Object InterfacePython is dynamically typed, unlike C++ which is statically - typed. Python variables may hold an integer, a float, list, dict, tuple, str, - long etc., among other things. In the viewpoint of Boost.Python and C++, these - Pythonic variables are just instances of class object. We - shall see in this chapter how to deal with Python objects. + Python is dynamically typed, unlike C++ which is statically typed. Python variables + may hold an integer, a float, list, dict, tuple, str, long etc., among other + things. In the viewpoint of Boost.Python and C++, these Pythonic variables + are just instances of class object. We shall see in this + chapter how to deal with Python objects.

    As mentioned, one of the goals of Boost.Python is to provide a bidirectional @@ -44,21 +44,24 @@ C++ objects are as close as possible to Python. This should minimize the learning curve significantly.

    -

    +

    + python +

    Basic Interface

    - Basic InterfaceClass object wraps PyObject*. - All the intricacies of dealing with PyObjects such as - managing reference counting are handled by the object - class. C++ object interoperability is seamless. Boost.Python C++ objects + Class object wraps PyObject*. All the + intricacies of dealing with PyObjects such as managing + reference counting are handled by the object class. C++ + object interoperability is seamless. Boost.Python C++ objects can in fact be explicitly constructed from any C++ object.

    To illustrate, this Python code snippet:

    -

    +

    +

     def f(x, y):
          if (y == 'foo'):
    @@ -73,7 +76,8 @@
     

    Can be rewritten in C++ using Boost.Python facilities this way:

    -

    +

    +

     object f(object x, object y) {
          if (y == "foo")
    @@ -95,8 +99,8 @@
     

    Derived Object types

    - Derived Object typesBoost.Python comes with a set of derived object - types corresponding to that of Python's: + Boost.Python comes with a set of derived object types + corresponding to that of Python's:

    • @@ -133,7 +137,8 @@
       d.keys()
       
      -

      make_tuple is provided for declaring tuple literals. +

      + make_tuple is provided for declaring tuple literals. Example:

      @@ -173,10 +178,9 @@
             

    boost.png (6897 bytes)Boost C++ Libraries Home Libraries People
    - +
    - Beware the common pitfall of forgetting that - the constructors of most of Python's mutable types make copies, just - as in Python.
    alert Beware the + common pitfall of forgetting that the constructors of most of Python's + mutable types make copies, just as in Python.

    Python: @@ -193,7 +197,7 @@ d['whatever'] = 3; // modifies the copy

    - + class_<T> as objects

    @@ -218,9 +222,9 @@

    Extracting C++ objects

    - Extracting C++ objectsAt some point, we will need to get C++ values out of - object instances. This can be achieved with the extract<T> - function. Consider the following: + At some point, we will need to get C++ values out of object instances. This + can be achieved with the extract<T> function. Consider + the following:

     double x = o.attr("length"); // compile error
    @@ -253,8 +257,8 @@
     if (x.check()) {
         Vec2& v = x(); ...
     
    -

    - The astute reader might have noticed that the extract<T> +

    + tip The astute reader might have noticed that the extract<T> facility in fact solves the mutable copying problem:

    @@ -266,12 +270,12 @@
     

    Enums

    - EnumsBoost.Python has a nifty facility to capture and wrap C++ enums. While - Python has no enum type, we'll often want to expose our - C++ enums to Python as an int. Boost.Python's enum facility - makes this easy while taking care of the proper conversions from Python's - dynamic typing to C++'s strong static typing (in C++, ints cannot be implicitly - converted to enums). To illustrate, given a C++ enum: + Boost.Python has a nifty facility to capture and wrap C++ enums. While Python + has no enum type, we'll often want to expose our C++ enums + to Python as an int. Boost.Python's enum facility makes + this easy while taking care of the proper conversions from Python's dynamic + typing to C++'s strong static typing (in C++, ints cannot be implicitly converted + to enums). To illustrate, given a C++ enum:

     enum choice { red, blue };
    @@ -293,16 +297,17 @@
           

    - +
    - what is a scope?

    The scope is a - class that has an associated global Python object which controls the - Python namespace in which new extension classes and wrapped functions - will be defined as attributes. Details can be found here.
    note what is a scope?
    +
    The scope is a class that has an associated global Python object + which controls the Python namespace in which new extension classes + and wrapped functions will be defined as attributes. Details can be + found here.

    You can access those values in Python as

    -

    +

    +

     >>> my_module.choice.red
     my_module.choice.red
    @@ -311,7 +316,8 @@
             where my_module is the module where the enum is declared. You can also create
             a new scope around a class:
           

    -

    +

    +

     scope in_X = class_<X>("X")
                     .def( ... )
    diff --git a/doc/tutorial/doc/html/python/techniques.html b/doc/tutorial/doc/html/python/techniques.html
    index 87f7798c..4f57d5b4 100644
    --- a/doc/tutorial/doc/html/python/techniques.html
    +++ b/doc/tutorial/doc/html/python/techniques.html
    @@ -10,7 +10,7 @@
     
     
     
    -
    +
    @@ -30,16 +30,16 @@
     
    Reducing Compiling Time

    - General TechniquesHere are presented some useful techniques that you can use - while wrapping code with Boost.Python. + Here are presented some useful techniques that you can use while wrapping code + with Boost.Python.

    Creating Packages

    - Creating PackagesA Python package is a collection of modules that provide - to the user a certain functionality. If you're not familiar on how to create - packages, a good introduction to them is provided in the Python + A Python package is a collection of modules that provide to the user a certain + functionality. If you're not familiar on how to create packages, a good introduction + to them is provided in the Python Tutorial.

    @@ -98,12 +98,10 @@

    boost.png (6897 bytes)Boost C++ Libraries Home Libraries People
    - +
    - - The extension .pyd is used for python extension - modules, which are just shared libraries. Using the default for your - system, like .so for Unix and .dll - for Windows, works just as well.
    note The extension .pyd is used + for python extension modules, which are just shared libraries. Using + the default for your system, like .so for Unix and + .dll for Windows, works just as well.

    Now, we create this directory structure for our Python package: @@ -124,7 +122,8 @@ into his PYTHONPATH and fire up the interpreter:

    -

    +

    +

     >>> import sounds.io
     >>> import sounds.filters
    @@ -146,7 +145,8 @@
             If we want this flexibility, we will have to complicate our package hierarchy
             a little. First, we will have to change the name of the extension modules:
           

    -

    +

    +

     /* file core.cpp */
     BOOST_PYTHON_MODULE(_core)
    @@ -178,7 +178,8 @@
             to each one. But if we leave it that way, the user will have to access the
             functions in the core module with this syntax:
           

    -

    +

    +

     >>> import sounds.core._core
     >>> sounds.core._core.foo(...)
    @@ -237,8 +238,8 @@
     

    Extending Wrapped Objects in Python

    - Extending Wrapped Objects in PythonThanks to Python's flexibility, you can - easily add new methods to a class, even after it was already created: + Thanks to Python's flexibility, you can easily add new methods to a class, + even after it was already created:

     >>> class C(object): pass
    @@ -256,12 +257,14 @@
     A C instance!
     

    - Yes, Python rox.

    + Yes, Python rox. smiley +

    We can do the same with classes that were wrapped with Boost.Python. Suppose we have a class point in C++:

    -

    +

    +

     class point {...};
     
    @@ -274,7 +277,8 @@
             If we are using the technique from the previous session, Creating
             Packages, we can code directly into geom/__init__.py:
           

    -

    +

    +

     from _geom import *
     
    @@ -285,7 +289,8 @@
     # now we turn it into a member function
     point.__str__ = point_str
     
    -

    All point instances created from C++ will +

    + All point instances created from C++ will also have this member function! This technique has several advantages:

      @@ -357,12 +362,13 @@

      Reducing Compiling Time

      - Reducing Compiling TimeIf you have ever exported a lot of classes, you know - that it takes quite a good time to compile the Boost.Python wrappers. Plus - the memory consumption can easily become too high. If this is causing you - problems, you can split the class_ definitions in multiple files: + If you have ever exported a lot of classes, you know that it takes quite + a good time to compile the Boost.Python wrappers. Plus the memory consumption + can easily become too high. If this is causing you problems, you can split + the class_ definitions in multiple files: +

      +

      -

       /* file point.cpp */
       #include <point.h>
      @@ -421,19 +427,16 @@
             

      -
      - - If you're exporting your classes with Pyste, +
      note If you're exporting your classes with Pyste, take a look at the --multiple option, that generates the wrappers in various files as demonstrated here.
      - +
      - - This method is useful too if you are getting the error message "fatal - error C1204:Compiler limit:internal structure overflow" - when compiling a large source file, as explained in the FAQ.
      note This method is useful too if you are getting the + error message "fatal error C1204:Compiler limit:internal + structure overflow" when compiling a large source file, + as explained in the FAQ.
    diff --git a/doc/tutorial/doc/tutorial.qbk b/doc/tutorial/doc/tutorial.qbk index cce8dfc7..0c49dee7 100644 --- a/doc/tutorial/doc/tutorial.qbk +++ b/doc/tutorial/doc/tutorial.qbk @@ -252,9 +252,10 @@ if you are on Windows, and if you are on Unix. [^boost_python.dll] and [^hello.pyd] can be found somewhere in your project's -[^bin] directory. After a successful build, you can just link in these DLLs with -the Python interpreter. In Windows for example, you can simply put these libraries -inside the directory where the Python executable is. +[^bin] directory. After a successful build, you make it possible for the system +to find boost_python.dll or libboost_python.so (usually done with LD_LIBRARY_PATH, +DYLD_LIBRARY_PATH, or some other variable on *nix and with PATH on Windows) and +for Python to find the hello module (Done with PYTHONPATH on all systems.) You may now fire up Python and run our hello module: