⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bpl.txt

📁 boost库提供标准的C++ API 配合dev c++使用,功能更加强大
💻 TXT
📖 第 1 页 / 共 3 页
字号:
GCC_XML_, which generates an XML version of GCC's internal program
representation.  Since GCC is a highly-conformant C++ compiler, this
ensures correct handling of the most-sophisticated template code and
full access to the underlying type system.  In keeping with the
Boost.Python philosophy, a Pyste interface description is neither
intrusive on the code being wrapped, nor expressed in some unfamiliar
language: instead it is a 100% pure Python script.  If Pyste is
successful it will mark a move away from wrapping everything directly
in C++ for many of our users.  It will also allow us the choice to
shift some of the metaprogram code from C++ to Python.  We expect that
soon, not only our users but the Boost.Python developers themselves
will be "thinking hybrid" about their own code.

.. _`GCC_XML`: http://www.gccxml.org/HTML/Index.html
.. _`Pyste`: http://www.boost.org/libs/python/pyste

---------------
 Serialization
---------------

*Serialization* is the process of converting objects in memory to a
form that can be stored on disk or sent over a network connection. The
serialized object (most often a plain string) can be retrieved and
converted back to the original object. A good serialization system will
automatically convert entire object hierarchies. Python's standard
``pickle`` module is just such a system.  It leverages the language's strong
runtime introspection facilities for serializing practically arbitrary
user-defined objects. With a few simple and unintrusive provisions this
powerful machinery can be extended to also work for wrapped C++ objects.
Here is an example::

    #include <string>

    struct World
    {
        World(std::string a_msg) : msg(a_msg) {}
        std::string greet() const { return msg; }
        std::string msg;
    };

    #include <boost/python.hpp>
    using namespace boost::python;

    struct World_picklers : pickle_suite
    {
      static tuple
      getinitargs(World const& w) { return make_tuple(w.greet()); }
    };

    BOOST_PYTHON_MODULE(hello)
    {
        class_<World>("World", init<std::string>())
            .def("greet", &World::greet)
            .def_pickle(World_picklers())
        ;
    }

Now let's create a ``World`` object and put it to rest on disk::

    >>> import hello
    >>> import pickle
    >>> a_world = hello.World("howdy")
    >>> pickle.dump(a_world, open("my_world", "w"))

In a potentially *different script* on a potentially *different
computer* with a potentially *different operating system*::

    >>> import pickle
    >>> resurrected_world = pickle.load(open("my_world", "r"))
    >>> resurrected_world.greet()
    'howdy'

Of course the ``cPickle`` module can also be used for faster
processing.

Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol
defined in the standard Python documentation. Like a __getinitargs__
function in Python, the pickle_suite's getinitargs() is responsible for
creating the argument tuple that will be use to reconstruct the pickled
object.  The other elements of the Python pickling protocol,
__getstate__ and __setstate__ can be optionally provided via C++
getstate and setstate functions.  C++'s static type system allows the
library to ensure at compile-time that nonsensical combinations of
functions (e.g. getstate without setstate) are not used.

Enabling serialization of more complex C++ objects requires a little
more work than is shown in the example above. Fortunately the
``object`` interface (see next section) greatly helps in keeping the
code manageable.

------------------
 Object interface
------------------

Experienced 'C' language extension module authors will be familiar
with the ubiquitous ``PyObject*``, manual reference-counting, and the
need to remember which API calls return "new" (owned) references or
"borrowed" (raw) references.  These constraints are not just
cumbersome but also a major source of errors, especially in the
presence of exceptions.

Boost.Python provides a class ``object`` which automates reference
counting and provides conversion to Python from C++ objects of
arbitrary type.  This significantly reduces the learning effort for
prospective extension module writers.

Creating an ``object`` from any other type is extremely simple::

    object s("hello, world");  // s manages a Python string

``object`` has templated interactions with all other types, with
automatic to-python conversions. It happens so naturally that it's
easily overlooked::

   object ten_Os = 10 * s[4]; // -> "oooooooooo"

In the example above, ``4`` and ``10`` are converted to Python objects
before the indexing and multiplication operations are invoked.

The ``extract<T>`` class template can be used to convert Python objects
to C++ types::

    double x = extract<double>(o);

If a conversion in either direction cannot be performed, an
appropriate exception is thrown at runtime.

The ``object`` type is accompanied by a set of derived types
that mirror the Python built-in types such as ``list``, ``dict``,
``tuple``, etc. as much as possible. This enables convenient
manipulation of these high-level types from C++::

    dict d;
    d["some"] = "thing";
    d["lucky_number"] = 13;
    list l = d.keys();

This almost looks and works like regular Python code, but it is pure
C++.  Of course we can wrap C++ functions which accept or return
``object`` instances.

=================
 Thinking hybrid
=================

Because of the practical and mental difficulties of combining
programming languages, it is common to settle a single language at the
outset of any development effort.  For many applications, performance
considerations dictate the use of a compiled language for the core
algorithms.  Unfortunately, due to the complexity of the static type
system, the price we pay for runtime performance is often a
significant increase in development time.  Experience shows that
writing maintainable C++ code usually takes longer and requires *far*
more hard-earned working experience than developing comparable Python
code.  Even when developers are comfortable working exclusively in
compiled languages, they often augment their systems by some type of
ad hoc scripting layer for the benefit of their users without ever
availing themselves of the same advantages.

Boost.Python enables us to *think hybrid*.  Python can be used for
rapidly prototyping a new application; its ease of use and the large
pool of standard libraries give us a head start on the way to a
working system.  If necessary, the working code can be used to
discover rate-limiting hotspots.  To maximize performance these can
be reimplemented in C++, together with the Boost.Python bindings
needed to tie them back into the existing higher-level procedure.

Of course, this *top-down* approach is less attractive if it is clear
from the start that many algorithms will eventually have to be
implemented in C++.  Fortunately Boost.Python also enables us to
pursue a *bottom-up* approach.  We have used this approach very
successfully in the development of a toolbox for scientific
applications.  The toolbox started out mainly as a library of C++
classes with Boost.Python bindings, and for a while the growth was
mainly concentrated on the C++ parts.  However, as the toolbox is
becoming more complete, more and more newly added functionality can be
implemented in Python.

.. image:: python_cpp_mix.jpg

This figure shows the estimated ratio of newly added C++ and Python
code over time as new algorithms are implemented.  We expect this
ratio to level out near 70% Python.  Being able to solve new problems
mostly in Python rather than a more difficult statically typed
language is the return on our investment in Boost.Python.  The ability
to access all of our code from Python allows a broader group of
developers to use it in the rapid development of new applications.

=====================
 Development history
=====================

The first version of Boost.Python was developed in 2000 by Dave
Abrahams at Dragon Systems, where he was privileged to have Tim Peters
as a guide to "The Zen of Python".  One of Dave's jobs was to develop
a Python-based natural language processing system.  Since it was
eventually going to be targeting embedded hardware, it was always
assumed that the compute-intensive core would be rewritten in C++ to
optimize speed and memory footprint [#proto]_.  The project also wanted to
test all of its C++ code using Python test scripts [#test]_.  The only
tool we knew of for binding C++ and Python was SWIG_, and at the time
its handling of C++ was weak.  It would be false to claim any deep
insight into the possible advantages of Boost.Python's approach at
this point.  Dave's interest and expertise in fancy C++ template
tricks had just reached the point where he could do some real damage,
and Boost.Python emerged as it did because it filled a need and
because it seemed like a cool thing to try.

This early version was aimed at many of the same basic goals we've
described in this paper, differing most-noticeably by having a
slightly more cumbersome syntax and by lack of special support for
operator overloading, pickling, and component-based development.
These last three features were quickly added by Ullrich Koethe and
Ralf Grosse-Kunstleve [#feature]_, and other enthusiastic contributors arrived
on the scene to contribute enhancements like support for nested
modules and static member functions.

By early 2001 development had stabilized and few new features were
being added, however a disturbing new fact came to light: Ralf had
begun testing Boost.Python on pre-release versions of a compiler using
the EDG_ front-end, and the mechanism at the core of Boost.Python
responsible for handling conversions between Python and C++ types was
failing to compile.  As it turned out, we had been exploiting a very
common bug in the implementation of all the C++ compilers we had
tested.  We knew that as C++ compilers rapidly became more
standards-compliant, the library would begin failing on more
platforms.  Unfortunately, because the mechanism was so central to the
functioning of the library, fixing the problem looked very difficult.

Fortunately, later that year Lawrence Berkeley and later Lawrence
Livermore National labs contracted with `Boost Consulting`_ for support
and development of Boost.Python, and there was a new opportunity to
address fundamental issues and ensure a future for the library.  A
redesign effort began with the low level type conversion architecture,
building in standards-compliance and support for component-based
development (in contrast to version 1 where conversions had to be
explicitly imported and exported across module boundaries).  A new
analysis of the relationship between the Python and C++ objects was
done, resulting in more intuitive handling for C++ lvalues and
rvalues.

The emergence of a powerful new type system in Python 2.2 made the
choice of whether to maintain compatibility with Python 1.5.2 easy:
the opportunity to throw away a great deal of elaborate code for
emulating classic Python classes alone was too good to pass up.  In
addition, Python iterators and descriptors provided crucial and
elegant tools for representing similar C++ constructs.  The
development of the generalized ``object`` interface allowed us to
further shield C++ programmers from the dangers and syntactic burdens
of the Python 'C' API.  A great number of other features including C++
exception translation, improved support for overloaded functions, and
most significantly, CallPolicies for handling pointers and
references, were added during this period.

In October 2002, version 2 of Boost.Python was released.  Development
since then has concentrated on improved support for C++ runtime
polymorphism and smart pointers.  Peter Dimov's ingenious
``boost::shared_ptr`` design in particular has allowed us to give the
hybrid developer a consistent interface for moving objects back and
forth across the language barrier without loss of information.  At
first, we were concerned that the sophistication and complexity of the
Boost.Python v2 implementation might discourage contributors, but the
emergence of Pyste_ and several other significant feature
contributions have laid those fears to rest.  Daily questions on the
Python C++-sig and a backlog of desired improvements show that the
library is getting used.  To us, the future looks bright.

.. _`EDG`: http://www.edg.com

=============
 Conclusions
=============

Boost.Python achieves seamless interoperability between two rich and
complimentary language environments.  Because it leverages template
metaprogramming to introspect about types and functions, the user
never has to learn a third syntax: the interface definitions are
written in concise and maintainable C++.  Also, the wrapping system
doesn't have to parse C++ headers or represent the type system: the
compiler does that work for us.

Computationally intensive tasks play to the strengths of C++ and are
often impossible to implement efficiently in pure Python, while jobs
like serialization that are trivial in Python can be very difficult in
pure C++.  Given the luxury of building a hybrid software system from
the ground up, we can approach design with new confidence and power.

===========
 Citations
===========

.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report,
   Vol. 7 No. 5 June 1995, pp. 26-31.
   http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html

===========
 Footnotes
===========

.. [#proto] In retrospect, it seems that "thinking hybrid" from the
        ground up might have been better for the NLP system: the
        natural component boundaries defined by the pure python
        prototype turned out to be inappropriate for getting the
        desired performance and memory footprint out of the C++ core,
        which eventually caused some redesign overhead on the Python
        side when the core was moved to C++.

.. [#test] We also have some reservations about driving all C++
        testing through a Python interface, unless that's the only way
        it will be ultimately used.  Any transition across language
        boundaries with such different object models can inevitably
        mask bugs.

.. [#feature] These features were expressed very differently in v1 of
        Boost.Python

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -