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

📄 quickstart.txt

📁 boost库提供标准的C++ API 配合dev c++使用,功能更加强大
💻 TXT
📖 第 1 页 / 共 5 页
字号:
[doc Boost Python Tutorial]

[def __note__       [$theme/note.gif]]
[def __alert__      [$theme/alert.gif]]
[def __detail__     [$theme/lens.gif]]
[def __tip__        [$theme/bulb.gif]]
[def :-)            [$theme/smiley.gif]]

[page QuickStart]

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).

[h2 Hello World]

Following C/C++ tradition, let's start with the "hello, world". A C++
Function:

    char const* greet()
    {
       return "hello, world";
    }

can be exposed to Python by writing a Boost.Python wrapper:

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

    BOOST_PYTHON_MODULE(hello)
    {
        def("greet", greet);
    }

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...]]]

[page Building Hello World]

[h2 From Start To Finish]

Now the first thing you'd want to do is to build the Hello World module and
try it for yourself in Python. In this section, we shall outline the steps
necessary to achieve that. We shall use the build tool that comes bundled
with every boost distribution: [*bjam].

[blurb __detail__ [*Building without bjam][br][br]

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.
]

We shall skip over the details. Our objective will be to simply create the
hello world module and run it in Python. For a complete reference to
building Boost.Python, check out: [@../../building.html building.html].
After this brief ['bjam] tutorial, we should have built two DLLs:

* boost_python.dll
* hello.pyd

if you are on Windows, and

* libboost_python.so
* hello.so

if you are on Unix.

The tutorial example can be found in the directory:
[^libs/python/example/tutorial]. There, you can find:

* hello.cpp
* Jamfile

The [^hello.cpp] file is our C++ hello world example. The [^Jamfile] is a
minimalist ['bjam] script that builds the DLLs for us.

Before anything else, you should have the bjam executable in your boost
directory or somewhere in your path such that [^bjam] can be executed in
the command line. Pre-built Boost.Jam executables are available for most
platforms. For example, a pre-built Microsoft Windows bjam executable can
be downloaded [@http://boost.sourceforge.net/jam-executables/bin.ntx86/bjam.zip here].
The complete list of bjam pre-built
executables can be found [@../../../../../tools/build/index.html#Jam here].

[h2 Lets Jam!]
[$theme/jam.png]

Here is our minimalist Jamfile:

[pre
    subproject libs/python/example/tutorial ;

    SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
    include python.jam ;

    extension hello                     # Declare a Python extension called hello
    :   hello.cpp                       # source
        <dll>../../build/boost_python   # dependencies
        ;
]

First, we need to specify our location in the boost project hierarchy.
It so happens that the tutorial example is located in [^/libs/python/example/tutorial].
Thus:

[pre
    subproject libs/python/example/tutorial ;
]

Then we will include the definitions needed by Python modules:

[pre
    SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
    include python.jam ;
]

Finally we declare our [^hello] extension:

[pre
    extension hello                     # Declare a Python extension called hello
    :   hello.cpp                       # source
        <dll>../../build/boost_python   # dependencies
        ;
]

[h2 Running bjam]

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

[:Start it up.]

Make sure that the environment is set so that we can invoke the C++
compiler. With MSVC, that would mean running the [^Vcvars32.bat] batch
file. For instance:

    C:\Program Files\Microsoft Visual Studio\VC98\bin\Vcvars32.bat

Some environment variables will have to be setup for proper building of our
Python modules. Example:

    set PYTHON_ROOT=c:/dev/tools/python
    set PYTHON_VERSION=2.2

The above assumes that the Python installation is in [^c:/dev/tools/python]
and that we are using Python version 2.2. You'll have to tweak this path
appropriately. __note__ Be sure not to include a third number, e.g. [*not]  "2.2.1",
even if that's the version you have.

Now we are ready... Be sure to [^cd] to [^libs/python/example/tutorial]
where the tutorial [^"hello.cpp"] and the [^"Jamfile"] is situated.

Finally:

    bjam -sTOOLS=msvc

We are again assuming that we are using Microsoft Visual C++ version 6. If
not, then you will have to specify the appropriate tool. See
[@../../../../../tools/build/index.html Building Boost Libraries] for
further details.

It should be building now:

[pre
    cd C:\dev\boost\libs\python\example\tutorial
    bjam -sTOOLS=msvc
    ...patience...
    ...found 1703 targets...
    ...updating 40 targets...
]

And so on... Finally:

[pre
    vc-C++ ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
    runtime-link-dynamic\hello.obj
    hello.cpp
    vc-Link ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
    runtime-link-dynamic\hello.pyd ..\..\..\..\libs\python\example\tutorial\bin\
    hello.pyd\msvc\debug\runtime-link-dynamic\hello.lib
       Creating library ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\
       msvc\debug\runtime-link-dynamic\hello.lib and object ..\..\..\..\libs\python\
       example\tutorial\bin\hello.pyd\msvc\debug\runtime-link-dynamic\hello.exp
    ...updated 40 targets...
]

If all is well, you should now have:

* boost_python.dll
* hello.pyd

if you are on Windows, and

* libboost_python.so
* hello.so

if you are on Unix.

[^boost_python.dll] can be found somewhere in [^libs\python\build\bin]
while [^hello.pyd] can be found somewhere in
[^libs\python\example\tutorial\bin]. 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.

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

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

[:[*There you go... Have fun!]]

[page Exposing Classes]

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

Consider a C++ class/struct that we want to expose to Python:

    struct World
    {
        void set(std::string msg) { this->msg = msg; }
        std::string greet() { return msg; }
        std::string msg;
    };

We can expose this to Python by writing a corresponding Boost.Python
C++ Wrapper:

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

    BOOST_PYTHON_MODULE(hello)
    {
        class_<World>("World")
            .def("greet", &World::greet)
            .def("set", &World::set)
        ;
    }

Here, we wrote a C++ class wrapper that exposes the member functions
[^greet] and [^set]. Now, after building our module as a shared library, we
may use our class [^World] in Python. Here's a sample Python session:

    >>> import hello
    >>> planet = hello.World()
    >>> planet.set('howdy')
    >>> planet.greet()
    'howdy'

[page:1 Constructors]

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()

We may wish to wrap a class with a non-default constructor. Let us
build on our previous example:

    struct World
    {
        World(std::string msg): msg(msg) {} // added constructor
        void set(std::string msg) { this->msg = msg; }
        std::string greet() { return msg; }
        std::string msg;
    };

This time [^World] has no default constructor; our previous
wrapping code would fail to compile when the library tried to expose
it. We have to tell [^class_<World>] about the constructor we want to
expose instead.

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

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

[^init<std::string>()] exposes the constructor taking in a
[^std::string] (in Python, constructors are spelled
"[^"__init__"]").

We can expose additional constructors by passing more [^init<...>]s to
the [^def()] member function. Say for example we have another World
constructor taking in two doubles:

    class_<World>("World", init<std::string>())
        .def(init<double, double>())
        .def("greet", &World::greet)
        .def("set", &World::set)
    ;

On the other hand, if we do not wish to expose any constructors at
all, we may use [^no_init] instead:

    class_<Abstract>("Abstract", no_init)

This actually adds an [^__init__] method which always raises a
Python RuntimeError exception.

[page:1 Class Data Members]

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]:

    struct Var
    {
        Var(std::string name) : name(name), value() {}
        std::string const name;
        float value;
    };

Our C++ [^Var] class and its data members can be exposed to Python:

    class_<Var>("Var", init<std::string>())
        .def_readonly("name", &Var::name)
        .def_readwrite("value", &Var::value);

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
    >>> print x.name, 'is around', x.value
    pi is around 3.14

Note that [^name] is exposed as [*read-only] while [^value] is exposed
as [*read-write].

[pre
    >>> x.name = 'e' # can't change name
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    AttributeError: can't set attribute
]

[page:1 Class Properties]

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:

⌨️ 快捷键说明

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