mirror of
https://github.com/boostorg/python.git
synced 2026-01-19 04:22:16 +00:00
boost-ification
[SVN r8335]
This commit is contained in:
@@ -1,21 +1,21 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<title>
|
||||
Building a Module with Py_cpp
|
||||
Building an Extension Module
|
||||
</title>
|
||||
<div>
|
||||
<h1>
|
||||
<img width="277" height="86" id="_x0000_i1025" align="center"
|
||||
src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">Building a Module with Py_cpp
|
||||
src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">Building an Extension Module
|
||||
</h1>
|
||||
<p>
|
||||
Right now, the only supported configuration is one in which the py_cpp
|
||||
Right now, the only supported configuration is one in which the BPL
|
||||
source files are statically linked with the source for your extension
|
||||
module. You may first build them into a library and link it with your
|
||||
extension module source, but the effect is the same as compiling all
|
||||
the source files together. Some users have successfully built the
|
||||
py_cpp sources into a shared library, and support for a shared library
|
||||
build is planned, but not yet implemented. The py_cpp source files are:
|
||||
sources into a shared library, and support for a shared library
|
||||
build is planned, but not yet implemented. The BPL source files are:
|
||||
<blockquote>
|
||||
<pre>
|
||||
<a href="../../../libs/python/src/extension_class.cpp">extclass.cpp</a>
|
||||
@@ -29,6 +29,7 @@
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>
|
||||
Next: <a href="enums.html">Enums</a>
|
||||
Previous: <a href="under-the-hood.html">A Peek Under the Hood</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
|
||||
@@ -12,14 +12,16 @@
|
||||
|
||||
<h2>CXX</h2>
|
||||
<p>
|
||||
Like py_cpp, <a href="http://cxx.sourceforge.net/">CXX</a> attempts to
|
||||
provide a C++-oriented interface to Python. In most cases, like py_cpp,
|
||||
it relieves the user from worrying about reference-counts. As far as I
|
||||
can tell, there is no support for subclassing C++ extension types in
|
||||
Python. An even more-significant difference is that a user's C++ code is
|
||||
still basically “dealing with Python objects”, though they are wrapped
|
||||
in C++ classes. This means such jobs as argument parsing and conversion
|
||||
are still left to be done explicitly by the user.
|
||||
Like BPL, <a href="http://cxx.sourceforge.net/">CXX</a> attempts to
|
||||
provide a C++-oriented interface to Python. In most cases, as with the
|
||||
boost library, it relieves the user from worrying about
|
||||
reference-counts. Both libraries automatically convert thrown C++
|
||||
exceptions into Python exceptions. As far as I can tell, CXX has no
|
||||
support for subclassing C++ extension types in Python. An even
|
||||
more significant difference is that a user's C++ code is still basically
|
||||
“dealing with Python objects”, though they are wrapped in
|
||||
C++ classes. This means such jobs as argument parsing and conversion are
|
||||
still left to be done explicitly by the user.
|
||||
|
||||
<p>
|
||||
CXX claims to interoperate well with the C++ Standard Library
|
||||
@@ -38,11 +40,9 @@
|
||||
<p>
|
||||
As far as I can tell, CXX enables one to write what is essentially
|
||||
idiomatic Python code in C++, manipulating Python objects through the
|
||||
same fully-generic interfaces we use in Python. I think it would be fair
|
||||
to say that while you're not programming directly to the “bare
|
||||
metal” with CXX, in comparison to py_cpp, it presents a low-level
|
||||
interface to Python. That use is also supported by the py_cpp object
|
||||
wrappers.
|
||||
same fully-generic interfaces we use in Python. While you're hardly programming directly to the “bare
|
||||
metal” with CXX, it basically presents a “C++-ized”
|
||||
version of the Python 'C' API.
|
||||
|
||||
<p>
|
||||
<a href="mailto:dubois1@llnl.gov">Paul F. Dubois</a>, the original
|
||||
@@ -65,7 +65,7 @@ that.”<br><i>-<a href="mailto:dubois1@llnl.gov">Paul Dubois</a></i>
|
||||
languages. Swig relies on a parser to read your source code and produce
|
||||
additional source code files which can be compiled into a Python (or
|
||||
Perl or Tcl) extension module. It has been successfully used to create
|
||||
many Python extension modules. Like py_cpp, SWIG is trying to allow an
|
||||
many Python extension modules. Like BPL, SWIG is trying to allow an
|
||||
existing interface to be wrapped with little or no change to the
|
||||
existing code. The documentation says “SWIG parses a form of ANSI C
|
||||
syntax that has been extended with a number of special directives. As a
|
||||
@@ -78,15 +78,15 @@ that.”<br><i>-<a href="mailto:dubois1@llnl.gov">Paul Dubois</a></i>
|
||||
couldnt handle templates, didnt do func overloading properly etc. For
|
||||
ANSI C libraries this was fine. But for usual C++ code this was a
|
||||
problem. Simple things work. But for anything very complicated (or
|
||||
realistic), one had to write code by hand. I believe py_cpp doesn't have
|
||||
realistic), one had to write code by hand. I believe BPL doesn't have
|
||||
this problem[<a href="#sic">sic</a>]... IMHO overloaded functions are very important to
|
||||
wrap correctly.”<br><i>-Prabhu Ramachandran</i>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
By contrast, py_cpp doesn't attempt to parse C++ - the problem is simply
|
||||
By contrast, BPL doesn't attempt to parse C++ - the problem is simply
|
||||
too complex to do correctly. <a name="sic">Technically</a>, one does
|
||||
write code by hand to use py_cpp. The goal, however, has been to make
|
||||
write code by hand to use BPL. The goal, however, has been to make
|
||||
that code nearly as simple as listing the names of the classes and
|
||||
member functions you want to expose in Python.
|
||||
|
||||
@@ -95,7 +95,7 @@ that.”<br><i>-<a href="mailto:dubois1@llnl.gov">Paul Dubois</a></i>
|
||||
<a
|
||||
href="http://www.thekompany.com/projects/pykde/background.php3?dhtml_ok=1">SIP</a>
|
||||
is a system similar to SWIG, though seemingly more
|
||||
C++-oriented. The author says that like py_cpp, SIP supports overriding
|
||||
C++-oriented. The author says that like BPL, SIP supports overriding
|
||||
extension class member functions in Python subclasses. It appears to
|
||||
have been designed specifically to directly support some features of
|
||||
PyQt/PyKDE, which is its primary client. Documentation is almost
|
||||
@@ -113,7 +113,7 @@ that.”<br><i>-<a href="mailto:dubois1@llnl.gov">Paul Dubois</a></i>
|
||||
to a wide range of computer languages, including Common Lisp, C++, C,
|
||||
Modula-3, and Python. ILU can parse the ISL to generate a C++ language
|
||||
header file describing the interface, of which the user is expected to
|
||||
provide an implementation. Unlike py_cpp, this means that the system
|
||||
provide an implementation. Unlike BPL, this means that the system
|
||||
imposes implementation details on your C++ code at the deepest level. It
|
||||
is worth noting that some of the C++ names generated by ILU are supposed
|
||||
to be reserved to the C++ implementation. It is unclear from the
|
||||
@@ -148,7 +148,7 @@ an inheritance relationship?
|
||||
<h2>Zope ExtensionClasses</h2>
|
||||
<p>
|
||||
<a href="http:http://www.digicool.com/releases/ExtensionClass">
|
||||
ExtensionClasses in Zope</a> use the same underlying mechanism as py_cpp
|
||||
ExtensionClasses in Zope</a> use the same underlying mechanism as BPL
|
||||
to support subclassing of extension types in Python, including
|
||||
multiple-inheritance. Both systems support pickling/unpickling of
|
||||
extension class instances in very similar ways. Both systems rely on the
|
||||
@@ -159,30 +159,30 @@ an inheritance relationship?
|
||||
The major differences are:
|
||||
<ul>
|
||||
<li>
|
||||
py_cpp lifts the burden on the user to parse and convert function
|
||||
BPL lifts the burden on the user to parse and convert function
|
||||
argument types. Zope provides no such facility.
|
||||
<li>
|
||||
py_cpp lifts the burden on the user to maintain Python
|
||||
BPL lifts the burden on the user to maintain Python
|
||||
reference-counts.
|
||||
<li>
|
||||
py_cpp supports function overloading; Zope does not.
|
||||
BPL supports function overloading; Zope does not.
|
||||
<li>
|
||||
py_cpp supplies a simple mechanism for exposing read-only and
|
||||
BPL supplies a simple mechanism for exposing read-only and
|
||||
read/write access to data members of the wrapped C++ type as Python
|
||||
attributes.
|
||||
<li>
|
||||
Writing a Zope ExtensionClass is significantly more complex than
|
||||
exposing a C++ class to python using py_cpp (mostly a summary of the
|
||||
exposing a C++ class to python using BPL (mostly a summary of the
|
||||
previous 4 items). <a href=
|
||||
"http://www.digicool.com/releases/ExtensionClass/MultiMapping.html">A
|
||||
Zope Example</a> illustrates the differences.
|
||||
<li>
|
||||
Zope's ExtensionClasses are specifically motivated by “the need for a
|
||||
C-based persistence mechanism”. Py_cpp's are motivated by the desire
|
||||
C-based persistence mechanism”. BPL's are motivated by the desire
|
||||
to simply reflect a C++ API into Python with as little modification as
|
||||
possible.
|
||||
<li>
|
||||
The following Zope restriction does not apply to py_cpp: “At most one
|
||||
The following Zope restriction does not apply to BPL: “At most one
|
||||
base extension direct or indirect super class may define C data
|
||||
members. If an extension subclass inherits from multiple base
|
||||
extension classes, then all but one must be mix-in classes that
|
||||
@@ -191,22 +191,22 @@ an inheritance relationship?
|
||||
Zope requires use of the somewhat funky inheritedAttribute (search for
|
||||
“inheritedAttribute” on <a
|
||||
href="http://www.digicool.com/releases/ExtensionClass">this page</a>)
|
||||
method to access base class methods. In py_cpp, base class methods can
|
||||
method to access base class methods. In BPL, base class methods can
|
||||
be accessed in the usual way by writing
|
||||
“<code>BaseClass.method</code>”.
|
||||
<li>
|
||||
Zope supplies some creative but esoteric idioms such as <a href=
|
||||
"http://www.digicool.com/releases/ExtensionClass/Acquisition.html">
|
||||
Acquisition</a>. No specific support for this is built into py_cpp.
|
||||
Acquisition</a>. No specific support for this is built into BPL.
|
||||
<li>
|
||||
Zope's ComputedAttribute support is designed to be used from Python.
|
||||
<a href="special.html#getter_setter">The analogous feature of
|
||||
py_cpp</a> can be used from C++ or Python. The feature is arguably
|
||||
easier to use in py_cpp.
|
||||
BPL</a> can be used from C++ or Python. The feature is arguably
|
||||
easier to use in BPL.
|
||||
</ul>
|
||||
<p>
|
||||
Next: <a href="example1.html">A Simple Example Using BPL</a>
|
||||
Previous: <a href="extending.html">A Brief Introduction to writing Python Extension Modules</a>
|
||||
Next: <a href="example1.html">A Simple Example Using py_cpp</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
|
||||
@@ -8,31 +8,36 @@
|
||||
<img width="277" height="86" id="_x0000_i1025" align="center"
|
||||
src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">Wrapping enums
|
||||
</h1>
|
||||
|
||||
<p>Because there is in general no way to deduce that a value of arbitrary type T
|
||||
is an enumeration constant, py_cpp cannot automatically convert enum values to
|
||||
and from Python. To handle this case, you need to decide how you want the enum
|
||||
to show up in Python (since Python doesn't have enums). Once you have done that,
|
||||
you can write some simple <code>from_python()</code> and
|
||||
<code>to_python()</code> functions.
|
||||
is an enumeration constant, the Boost Python Library cannot automatically
|
||||
convert enum values to and from Python. To handle this case, you need to decide
|
||||
how you want the enum to show up in Python (since Python doesn't have
|
||||
enums). Once you have done that, you can write some simple
|
||||
<code>from_python()</code> and <code>to_python()</code> functions.
|
||||
|
||||
<p>If you are satisfied with a Python int as a way to represent your enum
|
||||
values, py_cpp provides a shorthand for these functions. You just need to
|
||||
values, we provide a shorthand for these functions. You just need to
|
||||
instantiate <code>boost::python::enum_as_int_converters<EnumType></code> where
|
||||
<code>EnumType</code> is your enumerated type. There are two convenient ways to do this:
|
||||
|
||||
<ol>
|
||||
<li><blockquote>
|
||||
<pre>
|
||||
...
|
||||
} // close my_namespace
|
||||
// drop into namespace python and explicitly instantiate
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
|
||||
template class enum_as_int_converters<extclass_demo::EnumOwner::enum_type>;
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
namespace my_namespace { // re-open my_namespace
|
||||
...
|
||||
</pre>
|
||||
</blockquote>
|
||||
<li><blockquote><pre>
|
||||
// instantiate as base class in any namespace
|
||||
struct EnumTypeConverters
|
||||
: boost::python::py_enum_as_int_converters<EnumType>
|
||||
: boost::python::enum_as_int_converters<EnumType>
|
||||
{
|
||||
};
|
||||
</blockquote></pre>
|
||||
@@ -82,6 +87,10 @@ my_class.add(boost::python::to_python(enum_value_1), "enum_value_1");
|
||||
my_class.add(boost::python::to_python(enum_value_2), "enum_value_2");
|
||||
...
|
||||
</pre></blockquote>
|
||||
<p>
|
||||
Next: <a href="pointers.html">Pointers</a>
|
||||
Previous: <a href="building.html">Building an Extension Module</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<title>
|
||||
A Simple Example Using py_cpp
|
||||
A Simple Example Using BPL
|
||||
</title>
|
||||
<div>
|
||||
<h1>
|
||||
@@ -9,7 +9,7 @@
|
||||
"c++boost.gif (8819 bytes)">
|
||||
</h1>
|
||||
<h1>
|
||||
A Simple Example Using py_cpp
|
||||
A Simple Example Using BPL
|
||||
</h1>
|
||||
<p>
|
||||
Suppose we have the following C++ API which we want to expose in
|
||||
@@ -24,20 +24,20 @@ namespace hello {
|
||||
public:
|
||||
world(int);
|
||||
~world();
|
||||
std::string get() const { return "hi, world"; }
|
||||
std::string greet() const { return "hi, world"; }
|
||||
...
|
||||
};
|
||||
std::size_t length(const world& x) { return std::strlen(x.get()); }
|
||||
std::size_t length(const world& x) { return std::strlen(x.greet()); }
|
||||
}
|
||||
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>
|
||||
Here is the C++ code for a python module called <code>hello</code>
|
||||
which exposes the API using py_cpp:
|
||||
which exposes the API using BPL:
|
||||
<blockquote>
|
||||
<pre>
|
||||
#include <boost/python/class_builder.hpp>
|
||||
#include <boost/python/class_builder.hpp>
|
||||
// Python requires an exported function called init<module-name> in every
|
||||
// extension module. This is where we build the module contents.
|
||||
extern "C"
|
||||
@@ -49,15 +49,15 @@ void inithello()
|
||||
try
|
||||
{
|
||||
// create an object representing this extension module
|
||||
boost::python::module_builder hello("hello");
|
||||
boost::python::module_builder m("hello");
|
||||
// Create the Python type object for our extension class
|
||||
boost::python::class_builder<hello::world> world_class(hello, "world");
|
||||
boost::python::class_builder<hello::world> world_class(m, "world");
|
||||
// Add the __init__ function
|
||||
world_class.def(boost::python::constructor<int>());
|
||||
// Add a regular member function
|
||||
world_class.def(&hello::world::get, "get");
|
||||
// Add a regular function to the module
|
||||
hello.def(hello::length, "length");
|
||||
m.def(hello::length, "length");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
@@ -82,7 +82,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID)
|
||||
<pre>
|
||||
>>> import hello
|
||||
>>> hi_world = hello.world(3)
|
||||
>>> hi_world.get()
|
||||
>>> hi_world.greet()
|
||||
'hi, world'
|
||||
>>> hello.length(hi_world)
|
||||
9
|
||||
@@ -93,11 +93,11 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID)
|
||||
<blockquote>
|
||||
<pre>
|
||||
>>> class my_subclass(hello.world):
|
||||
... def get(self):
|
||||
... def greet(self):
|
||||
... return 'hello, world'
|
||||
...
|
||||
>>> y = my_subclass(4)
|
||||
>>> y.get()
|
||||
>>> y.greet()
|
||||
'hello, world'
|
||||
</pre>
|
||||
</blockquote>
|
||||
@@ -115,7 +115,8 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID)
|
||||
to have a <code>length()</code> of <code>12</code>? If so, <a href=
|
||||
"overriding.html">read on</a>...
|
||||
<p>
|
||||
Previous: <a href="comparisons.html">Comparisons with other systems</a> Next: <a href="overriding.html">Overridable virtual functions</a> Up:
|
||||
Next: <a href="overriding.html">Overridable virtual functions</a>
|
||||
Previous: <a href="comparisons.html">Comparisons with other systems</a> Up:
|
||||
<a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
|
||||
@@ -38,11 +38,11 @@
|
||||
</ul>
|
||||
This last item typically occupies a great deal of code in an extension
|
||||
module. Remember that Python is a completely dynamic language. A callable
|
||||
object receives its arguments in a tuple; it is up to that object to
|
||||
extract those arguments from the tuple, check their types, and raise
|
||||
appropriate exceptions. There are numerous other tedious details that need
|
||||
to be managed; too many to mention here. Py_cpp is designed to lift most of
|
||||
that burden.<br>
|
||||
object receives its arguments in a tuple; it is up to that object to extract
|
||||
those arguments from the tuple, check their types, and raise appropriate
|
||||
exceptions. There are numerous other tedious details that need to be
|
||||
managed; too many to mention here. The Boost Python Library is designed to
|
||||
lift most of that burden.<br>
|
||||
<br>
|
||||
|
||||
<p>
|
||||
@@ -56,10 +56,10 @@
|
||||
sublcassing the extension type. Aside from being tedious, it's not really
|
||||
the same as having a true class, because there's no way for the user to
|
||||
override a method of the extension type which is called from the
|
||||
extension module. Py_cpp solves this problem by taking advantage of <a
|
||||
extension module. BPL solves this problem by taking advantage of <a
|
||||
href="http://www.python.org/doc/essays/metaclasses/">Python's metaclass
|
||||
feature</a> to provide objects which look, walk, and hiss almost exactly
|
||||
like regular Python classes. Py_cpp classes are actually cleaner than
|
||||
like regular Python classes. BPL classes are actually cleaner than
|
||||
Python classes in some subtle ways; a more detailed discussion will
|
||||
follow (someday).</p>
|
||||
<p>Next: <a href="comparisons.html">Comparisons with Other Systems</a> Up: <a
|
||||
|
||||
111
doc/index.html
111
doc/index.html
@@ -2,26 +2,22 @@
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<title>
|
||||
py_cpp Python/C++ binding documentation
|
||||
The Boost Python Library (BPL)
|
||||
</title>
|
||||
<h1>
|
||||
<img src="../../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277"
|
||||
align="center" height="86"> py_cpp<a href="#naming_contest">*</a>
|
||||
align="center" height="86">The Boost Python Library (BPL)
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
The source code for py_cpp, including a MSVC demo project is available <a
|
||||
href="py_cpp_20001106.zip">here</a>.
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
<p>
|
||||
py_cpp is a system for quickly and easily interfacing C++ code with <a
|
||||
href="http:www.python.org">Python</a> such that the Python interface is
|
||||
Use the Boost Python Library to quickly and easily export a C++ library to <a
|
||||
href="http://www.pythonlabs.com/pub/www.python.org">Python</a> such that the Python interface is
|
||||
very similar to the C++ interface. It is designed to be minimally
|
||||
intrusive on your C++ design. In most cases, you should not have to alter
|
||||
your C++ classes in any way in order to use them with py_cpp. The system
|
||||
your C++ classes in any way in order to use them with BPL. The system
|
||||
<em>should</em> simply “reflect” your C++ classes and functions into
|
||||
Python. The major features of py_cpp include support for:
|
||||
Python. The major features of BPL include support for:
|
||||
<ul>
|
||||
<li><a href="inheritance.hml">Subclassing extension types in Python</a>
|
||||
<li><a href="overriding.html">Overriding virtual functions in Python</a>
|
||||
@@ -32,7 +28,7 @@ among others.
|
||||
|
||||
|
||||
<h2>Supported Platforms</h2>
|
||||
<p>py_cpp has been tested in the following configurations:
|
||||
<p>BPL has been tested in the following configurations:
|
||||
|
||||
<ul>
|
||||
<li>Against Python 1.5.2 using the following compiler/library:
|
||||
@@ -56,7 +52,7 @@ among others.
|
||||
href="mailto:rwgk@cci.lbl.gov">Ralf W. Grosse-Kunstleve</a>]
|
||||
|
||||
<li>An upcoming release of <a href="http://www.metrowerks.com/products/windows/">Metrowerks CodeWarrior
|
||||
Pro6 for Windows</a> (the first release has a bug that's fatal to py_cpp)
|
||||
Pro6 for Windows</a> (the first release has a bug that's fatal to BPL)
|
||||
</ul>
|
||||
<br>
|
||||
<li>Against Python 2.0 using the following compiler/library combinations:
|
||||
@@ -67,18 +63,13 @@ among others.
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<p>Py_cpp requires the <a href="http://www.boost.org">boost</a> libraries, and is
|
||||
has been accepted for inclusion into the boost libraries pending “boostification“
|
||||
(completion of the documentation, change in some naming conventions and
|
||||
resolution of some namespace issues).
|
||||
|
||||
<h2>Credits</h2>
|
||||
<ul>
|
||||
<li><a href="mailto:abrahams@mediaone.net">David Abrahams</a> originated
|
||||
and wrote py_cpp.
|
||||
<li><a href="../../../people/dave_abrahams.htm">David Abrahams</a> originated
|
||||
and wrote the library.
|
||||
|
||||
<li><a href="mailto:koethe@informatik.uni-hamburg.de">Ullrich Koethe</a>
|
||||
had independently developed a similar system. When he discovered py_cpp,
|
||||
had independently developed a similar system. When he discovered BPL,
|
||||
he generously contributed countless hours of coding and much insight into
|
||||
improving it. He is responsible for an early version of the support for <a
|
||||
href="overloading.html">function overloading</a> and wrote the support for
|
||||
@@ -88,13 +79,13 @@ among others.
|
||||
exposing <a href="special.html#numeric">numeric operators</a>, including
|
||||
a way to avoid explicit coercion by means of overloading.
|
||||
|
||||
<li>The members of the boost mailing list and the Python community supplied
|
||||
invaluable early feedback. In particular, Ron Clarke, Mark Evans, Anton
|
||||
Gluck, Ralf W. Grosse-Kunstleve, Prabhu Ramachandran, and Barry Scott took
|
||||
the brave step of trying to use py_cpp while it was still in early stages
|
||||
of development.
|
||||
<li>The members of the boost mailing list and the Python community
|
||||
supplied invaluable early feedback. In particular, Ron Clarke, Mark Evans,
|
||||
Anton Gluck, Ralf W. Grosse-Kunstleve, Chuck Ingold, Prabhu Ramachandran,
|
||||
and Barry Scott took the brave step of trying to use BPL while it was
|
||||
still in early stages of development.
|
||||
|
||||
<li>The development of py_cpp wouldn't have been
|
||||
<li>The development of BPL wouldn't have been
|
||||
possible without the generous support of <a href="http://www.dragonsys.com/">Dragon Systems/Lernout and
|
||||
Hauspie, Inc</a> who supported its development as an open-source project.
|
||||
</ul>
|
||||
@@ -105,10 +96,10 @@ among others.
|
||||
<li><a href="extending.html">A Brief Introduction to writing Python
|
||||
extension modules</a>
|
||||
|
||||
<li><a href="comparisons.html">Comparisons between py_cpp and other
|
||||
<li><a href="comparisons.html">Comparisons between BPL and other
|
||||
systems for extending Python</a>
|
||||
|
||||
<li><a href="example1.html">A Simple Example Using py_cpp</a>
|
||||
<li><a href="example1.html">A Simple Example Using BPL</a>
|
||||
|
||||
<li><a href="overriding.html">Overridable Virtual Functions</a>
|
||||
|
||||
@@ -120,11 +111,13 @@ among others.
|
||||
|
||||
<li><a href="under-the-hood.html">A Peek Under the Hood</a>
|
||||
|
||||
<li><a href="building.html">Building a Module with Py_cpp</a>
|
||||
<li><a href="building.html">Building a Module with BPL</a>
|
||||
|
||||
<li>Advanced Topics
|
||||
|
||||
<ol>
|
||||
<li>Pickling
|
||||
|
||||
<li>class_builder<>
|
||||
|
||||
<li><a href="enums.html">enums</a>
|
||||
@@ -143,63 +136,17 @@ among others.
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
More sophisticated examples are given in
|
||||
<code>extclass_demo.cpp</code>, <code> extclass_demo.h</code>, and <code>
|
||||
test_extclass.py</code> in the <a href="py_cpp.tgz">source code
|
||||
archive</a>. There's much more here, and much more documentation to
|
||||
come...
|
||||
Documentation is a major ongoing project; assistance is greatly
|
||||
appreciated! In the meantime, useful examples of every BPL feature should
|
||||
be evident in the regression test files <code>test/comprehensive.[<a
|
||||
href="../test/comprehensive.py">py</a>/<a
|
||||
href="../test/comprehensive.hpp">hpp</a>/<a
|
||||
href="../test/comprehensive.cpp">cpp</a>]</code>
|
||||
|
||||
<p>
|
||||
Questions should be directed to <a href=
|
||||
"http://www.egroups.com/list/boost">the boost mailing list</a>.
|
||||
|
||||
<h2>Naming Contest</h2>
|
||||
|
||||
<p>
|
||||
Yes, I know py_cpp is a lousy name. Problem is, the best names my puny
|
||||
imagination can muster (IDLE and GRAIL) are taken, so I'm holding a
|
||||
naming contest. First prize? You get to pick the name<0.2wink> and
|
||||
you will be credited in the documentation. Names that have been suggested
|
||||
so far include:
|
||||
<ul>
|
||||
<li>
|
||||
Py++
|
||||
<li>
|
||||
Python++
|
||||
<li>
|
||||
Coil
|
||||
<li>
|
||||
SnakeSkin
|
||||
<li>
|
||||
CCCP - <b>C</b>onvert <b>C</b>++ <b>
|
||||
C</b>lasses to <b>P</b>ython
|
||||
<li>
|
||||
C<sup>3</sup>PO - <b>C</b>onvert <b>C</b>++
|
||||
<b>C</b>lasses to <b>P</b>ython <b>
|
||||
O</b>bjects
|
||||
<li>
|
||||
PALIN - <b>P</b>ython <b>
|
||||
A</b>ugmented-<b>L</b>anguage <b>
|
||||
IN</b>tegration
|
||||
<li>
|
||||
CLEESE - <b>C</b>++ <b>L</b>anguage <b>E</b>xtension <b>E</b>nvironment
|
||||
<b>S</b>upremely <b>E</b>asy
|
||||
<li>
|
||||
JONES - <b>J</b>ust <b>O</b>bscenely <b>N</b>eat <b>E</b>xtension
|
||||
<b>S</b>ystem
|
||||
<li>
|
||||
C-thru
|
||||
<li>
|
||||
SeamlessC
|
||||
<li>
|
||||
BorderCrossing
|
||||
<li>
|
||||
Perseus (because he solved a hairy problem involving snakes by using
|
||||
reflection and was invisible most of the time).
|
||||
</ul>
|
||||
Please <a href="http://www.egroups.com/list/boost">post</a> or send <a
|
||||
href="http:mailto:abrahams@mediaone.net">me</a> your suggestions!<br>
|
||||
<br>
|
||||
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
<h2>Inheritance in Python</h2>
|
||||
|
||||
<p>
|
||||
Py_cpp extension classes support single and multiple-inheritance in
|
||||
Python, just like regular Python classes. You can mix built-in Python
|
||||
classes with py_cpp extension classes in a derived class' tuple of
|
||||
bases. Whenever a py_cpp extension class is among the bases for a new
|
||||
class in Python, the result is an extension class:
|
||||
BPL extension classes support single and multiple-inheritance in
|
||||
Python, just like regular Python classes. You can arbitrarily mix
|
||||
built-in Python classes with extension classes in a derived class'
|
||||
tuple of bases. Whenever a BPL extension class is among the bases for a
|
||||
new class in Python, the result is an extension class:
|
||||
<blockquote>
|
||||
<pre>
|
||||
>>> class MyPythonClass:
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
<h2><a name="implicit_conversion">Reflecting C++ Inheritance Relationships</a></h2>
|
||||
<p>
|
||||
Py_cpp also allows us to represent C++ inheritance relationships so that
|
||||
BPL also allows us to represent C++ inheritance relationships so that
|
||||
wrapped derived classes may be passed where values, pointers, or
|
||||
references to a base class are expected as arguments. The
|
||||
<code>declare_base</code> member function of
|
||||
@@ -71,7 +71,11 @@ int get_derived_x(const Derived& d) {
|
||||
return d.x;
|
||||
}
|
||||
<hr>
|
||||
#include <boost/python/class_builder.hpp>
|
||||
#include <boost/python/class_builder.hpp>
|
||||
|
||||
// namespace alias for code brevity
|
||||
namespace python = boost::python;
|
||||
|
||||
extern "C"
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
@@ -80,13 +84,13 @@ void initmy_module()
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::python::module_builder my_module("my_module");
|
||||
python::module_builder my_module("my_module");
|
||||
|
||||
boost::python::class_builder<Base> base_class(my_module, "Base");
|
||||
base_class.def(boost::python::constructor<void>());
|
||||
python::class_builder<Base> base_class(my_module, "Base");
|
||||
base_class.def(python::constructor<void>());
|
||||
|
||||
boost::python::class_builder<Derived> derived_class(my_module, "Derived");
|
||||
derived_class.def(boost::python::constructor<void>());
|
||||
python::class_builder<Derived> derived_class(my_module, "Derived");
|
||||
derived_class.def(python::constructor<void>());
|
||||
<b>// Establish the inheritance relationship between Base and Derived
|
||||
derived_class.declare_base(base_class);</b>
|
||||
|
||||
@@ -96,7 +100,7 @@ void initmy_module()
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
boost::python::handle_exception(); // Deal with the exception for Python
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
@@ -135,12 +139,12 @@ struct Base2 {};
|
||||
struct Derived2 { int f(); };
|
||||
<hr>
|
||||
...
|
||||
boost::python::class_builder<Base> base2_class(my_module, "Base2");
|
||||
base2_class.def(boost::python::constructor<void>());
|
||||
python::class_builder<Base> base2_class(my_module, "Base2");
|
||||
base2_class.def(python::constructor<void>());
|
||||
|
||||
boost::python::class_builder<Derived2> derived2_class(my_module, "Derived2");
|
||||
derived2_class.def(boost::python::constructor<void>());
|
||||
derived_class.declare_base(base_class, <b>boost::python::without_downcast</b>);
|
||||
python::class_builder<Derived2> derived2_class(my_module, "Derived2");
|
||||
derived2_class.def(python::constructor<void>());
|
||||
derived_class.declare_base(base_class, <b>python::without_downcast</b>);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
@@ -150,8 +154,8 @@ struct Derived2 { int f(); };
|
||||
references, or values.
|
||||
|
||||
<p>
|
||||
Next: <a href="special.html">Special Method and Operator Support</a>
|
||||
Previous: <a href="overloading.html">Function Overloading</a>
|
||||
Next: <a href="special.html">Special Method Names</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
|
||||
@@ -113,8 +113,7 @@ namespace scope as Python member functions.
|
||||
|
||||
<h2>Overload Resolution</h2>
|
||||
<p>
|
||||
The function overload resolution mechanism in py_cpp works as
|
||||
follows:
|
||||
The function overload resolution mechanism works as follows:
|
||||
|
||||
<ul>
|
||||
|
||||
@@ -141,8 +140,8 @@ namespace scope as Python member functions.
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Prev: <a href="overriding.html">Overridable Virtual Functions</a>
|
||||
Next: <a href="inheritance.html">Special Method Names</a>
|
||||
Next: <a href="inheritance.html">Inheritance</a>
|
||||
Previous: <a href="overriding.html">Overridable Virtual Functions</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<h2><a name="overriding_example">Example</a></h2>
|
||||
|
||||
<p>In this example, it is assumed that <code>world::get()</code> is a virtual
|
||||
<p>In this example, it is assumed that <code>world::greet()</code> is a virtual
|
||||
member function:
|
||||
|
||||
<blockquote><pre>
|
||||
@@ -26,7 +26,7 @@ class world
|
||||
public:
|
||||
world(int);
|
||||
virtual ~world();
|
||||
<b>virtual</b> std::string get() const { return "hi, world"; }
|
||||
<b>virtual</b> std::string greet() const { return "hi, world"; }
|
||||
};
|
||||
</pre></blockquote>
|
||||
|
||||
@@ -65,11 +65,11 @@ struct world_callback : world
|
||||
: world(x),
|
||||
m_self(self) {}
|
||||
|
||||
std::string get() const // <a href="#derived_3">3</a>
|
||||
std::string greet() const // <a href="#derived_3">3</a>
|
||||
{ return boost::python::callback<std::string>::call_method(m_self, "get"); }
|
||||
|
||||
static std::string <a name= "default_implementation">default_get</a>(const hello::world& self) const // <a href="#derived_4">4</a>
|
||||
{ return self.world::get(); }
|
||||
{ return self.world::greet(); }
|
||||
private:
|
||||
PyObject* m_self; // <a href="#derived_1">1</a>
|
||||
};
|
||||
@@ -94,7 +94,7 @@ world_class.def(&world::get, "get", &<b>world_callback::default_get</b>)
|
||||
|
||||
<blockquote><pre>
|
||||
>>> class my_subclass(hello.world):
|
||||
... def get(self):
|
||||
... def greet(self):
|
||||
... return 'hello, world'
|
||||
...
|
||||
>>> hello.length(my_subclass())
|
||||
@@ -181,9 +181,9 @@ break the <a
|
||||
href="http://cs.calvin.edu/c++/C++Standard-Nov97/basic.html#basic.def.odr">ODR</a>).
|
||||
|
||||
<p>
|
||||
Prev: <a href="example1.html">A Simple Example Using py_cpp</a> Next: <a
|
||||
href="overloading.html">Function Overloading</a> Up: <a href=
|
||||
"index.html">Top</a>
|
||||
Next: <a href="overloading.html">Function Overloading</a>
|
||||
Previous: <a href="example1.html">A Simple Example Using py_cpp</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
<p>
|
||||
In general, raw pointers passed to or returned from functions are problematic
|
||||
for py_cpp because pointers have too many potential meanings. Is it an iterator?
|
||||
for BPL because pointers have too many potential meanings. Is it an iterator?
|
||||
A pointer to a single element? An array? When used as a return value, is the
|
||||
caller expected to manage (delete) the pointed-to object or is the pointer
|
||||
really just a reference? If the latter, what happens to Python references to the
|
||||
@@ -35,11 +35,9 @@ converted from/to Python strings.
|
||||
|
||||
<p>My first piece of advice to anyone with a case not covered above is
|
||||
“find a way to avoid the problem.” For example, if you have just one
|
||||
or two functions returning a pointer to a single (not an array of) <code>const
|
||||
T*</code> for some wrapped <code>T</code>, you may be able to write a “thin
|
||||
converting wrapper” over those two functions as follows (Since py_cpp
|
||||
converts <code>const T&</code> values <code>to_python</code> by copying the T
|
||||
into a new extension instance, Foo must have a public copy constructor):
|
||||
or two functions that return a pointer to an individual <code>const
|
||||
T</code>, and <code>T</code> is a wrapped class, you may be able to write a “thin
|
||||
converting wrapper” over those two functions as follows:
|
||||
|
||||
<blockquote><pre>
|
||||
const Foo* f(); // original function
|
||||
@@ -47,6 +45,10 @@ const Foo& f_wrapper() { return *f(); }
|
||||
...
|
||||
my_module.def(f_wrapper, "f");
|
||||
</pre></blockquote>
|
||||
<p>
|
||||
Foo must have a public copy constructor for this technique to work, since BPL
|
||||
converts <code>const T&</code> values <code>to_python</code> by copying the <code>T</code>
|
||||
value into a new extension instance.
|
||||
|
||||
<h2>Dealing with the problem</h2>
|
||||
|
||||
@@ -118,7 +120,7 @@ return value. You can handle this case by returning a Python tuple:
|
||||
typedef unsigned ErrorCode;
|
||||
const char* f(int* in_out_x); // original function
|
||||
...
|
||||
#include <boost/python/objects.hpp>
|
||||
#include <boost/python/objects.hpp>
|
||||
const boost::python::tuple f_wrapper(int in_x) {
|
||||
const char* s = f(in_x);
|
||||
return boost::python::tuple(s, in_x);
|
||||
@@ -131,8 +133,9 @@ my_module.def(f_wrapper, "f");
|
||||
>>> str,out_x = f(3)
|
||||
</pre></blockquote>
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
Previous: <a href="enums.html">Enums</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
Overview
|
||||
</h2>
|
||||
<p>
|
||||
Py_cpp supports all of the standard <a href=
|
||||
BPL supports all of the standard <a href=
|
||||
"http://www.pythonlabs.com/pub/www.python.org/doc/current/ref/specialnames.html">
|
||||
special method names</a> supported by real Python class instances <em>
|
||||
except</em> <code>__complex__</code> (more on the reasons <a href=
|
||||
@@ -100,7 +100,7 @@ std::string to_string(Foo const& f)
|
||||
boost::python::class_builder<Foo> foo_class(my_module, "Foo");
|
||||
foo_class.def(&to_string, "__str__");
|
||||
</pre></blockquote>
|
||||
Note that py_cpp also supports <em>automatic wrapping</em> of
|
||||
Note that BPL also supports <em>automatic wrapping</em> of
|
||||
<code>__str__</code> and <code>__cmp__</code>. This is explained in the <a
|
||||
href="#numeric">next section</a> and the <a href="#numeric_table">Table of
|
||||
Automatically Wrapped Methods</a>.
|
||||
@@ -113,7 +113,7 @@ foo_class.def(&to_string, "__str__");
|
||||
href="http://www.pythonlabs.com/pub/www.python.org/doc/current/ref/numeric-types.html">numeric
|
||||
protocols</a>. This is the basic same technique used to expose
|
||||
<code>to_string()</code> as <code>__str__()</code> above, and is <a
|
||||
href="#numeric_manual">covered in detail below</a>. Py_cpp also supports
|
||||
href="#numeric_manual">covered in detail below</a>. BPL also supports
|
||||
<i>automatic wrapping</i> of numeric operators whenever they have already
|
||||
been defined in C++.
|
||||
|
||||
@@ -170,7 +170,7 @@ a = i + b;
|
||||
bignum_class.def(boost::python::operators<boost::python::op_add>(), boost::python::right_operand<int>());
|
||||
bignum_class.def(boost::python::operators<boost::python::op_add>(), boost::python::left_operand<int>());
|
||||
</pre></blockquote>
|
||||
Py_cpp uses overloading to register several variants of the same
|
||||
BPL uses overloading to register several variants of the same
|
||||
operation (more on this in the context of <a href="#coercion">
|
||||
coercion</a>). Again, several operators can be exported at once:
|
||||
<blockquote><pre>
|
||||
@@ -276,13 +276,13 @@ bignum_class.def(&rmod, "__rmod__");
|
||||
coercion functions can be difficult if many type combinations must be
|
||||
supported.
|
||||
<p>
|
||||
Py_cpp solves this problem the same way that C++ does: with <em><a
|
||||
BPL solves this problem the same way that C++ does: with <em><a
|
||||
href="overloading.html">overloading</a></em>. This technique drastically
|
||||
simplifies the code neccessary to support operators: you just register
|
||||
operators for all desired type combinations, and py_cpp automatically
|
||||
operators for all desired type combinations, and BPL automatically
|
||||
ensures that the correct function is called in each case; there is no
|
||||
need for user-defined coercion functions. To enable operator
|
||||
overloading, py_cpp provides a standard coercion which is <em>implicitly
|
||||
overloading, BPL provides a standard coercion which is <em>implicitly
|
||||
registered</em> whenever automatic operator wrapping is used.
|
||||
<p>
|
||||
If you wrap all operator functions manually, but still want to use
|
||||
@@ -354,7 +354,7 @@ bignum_class.def((ternary_function2)&power, "__pow__");
|
||||
|
||||
In the second variant, however, <code>BigNum</code> appears only as second
|
||||
argument, and in the last one it is the third argument. These functions
|
||||
must be presented to py_cpp such that that the <code>BigNum</code>
|
||||
must be presented to BPL such that that the <code>BigNum</code>
|
||||
argument appears in first position:
|
||||
|
||||
<blockquote><pre>
|
||||
@@ -381,7 +381,7 @@ Note that "__rrpow__" is an extension not present in plain Python.
|
||||
|
||||
<h2><a name="numeric_table">Table of Automatically Wrapped Methods</a></h2>
|
||||
<p>
|
||||
Py_cpp can automatically wrap the following <a href=
|
||||
BPL can automatically wrap the following <a href=
|
||||
"http://www.pythonlabs.com/pub/www.python.org/doc/current/ref/specialnames.html">
|
||||
special methods</a>:
|
||||
|
||||
@@ -755,13 +755,13 @@ KeyError: 2
|
||||
<h2><a name="getter_setter">Customized Attribute Access</a></h2>
|
||||
|
||||
<p>
|
||||
Just like built-in Python classes, py_cpp extension classes support <a
|
||||
Just like built-in Python classes, BPL extension classes support <a
|
||||
href="http://www.pythonlabs.com/pub/www.python.org/doc/current/ref/attribute-access.html">special
|
||||
the usual attribute access methods</a> <code>__getattr__</code>,
|
||||
<code>__setattr__</code>, and <code>__delattr__</code>.
|
||||
Because writing these functions can
|
||||
be tedious in the common case where the attributes being accessed are
|
||||
known statically, py_cpp checks the special names
|
||||
known statically, BPL checks the special names
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
@@ -777,7 +777,7 @@ KeyError: 2
|
||||
following shows how we can implement a “computed attribute” in Python:
|
||||
<blockquote>
|
||||
<pre>
|
||||
>>> class Range(AnyPy_cppExtensionClass):
|
||||
>>> class Range(AnyBPLExtensionClass):
|
||||
... def __init__(self, start, end):
|
||||
... self.start = start
|
||||
... self.end = end
|
||||
@@ -793,7 +793,7 @@ KeyError: 2
|
||||
Direct Access to Data Members
|
||||
</h4>
|
||||
<p>
|
||||
Py_cpp uses the special <code>
|
||||
BPL uses the special <code>
|
||||
__xxxattr__<em><name></em>__</code> functionality described above
|
||||
to allow direct access to data members through the following special
|
||||
functions on <code>class_builder<></code> and <code>
|
||||
@@ -873,9 +873,9 @@ if (PyInstance_Check(r)) { ...
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>
|
||||
Previous: <a href="inheritance.html">Inheritance</a> Next: <a href=
|
||||
"under-the-hood.html">A Peek Under the Hood</a> Up: <a href=
|
||||
"index.html">Top</a>
|
||||
Next: <a href="under-the-hood.html">A Peek Under the Hood</a>
|
||||
Previous: <a href="inheritance.html">Inheritance</a>
|
||||
Up: <a href= "index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams and Ullrich Köthe 2000.
|
||||
Permission to copy, use, modify, sell and distribute this document is
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"example1.html#add_world_class">add it to the module</a> it goes into the
|
||||
module's dictionary to be looked up under the name "world".
|
||||
<p>
|
||||
Py_cpp uses C++'s template argument deduction mechanism to determine the
|
||||
BPL uses C++'s template argument deduction mechanism to determine the
|
||||
types of arguments to functions (except constructors, for which we must
|
||||
<a href="example1.html#Constructor_example">provide an argument list</a>
|
||||
because they can't be named in C++). Then, it calls the appropriate
|
||||
@@ -48,8 +48,8 @@
|
||||
the top of your module's init function, then <code>def</code> the member
|
||||
functions later to avoid problems with inter-class dependencies.
|
||||
<p>
|
||||
Previous: <a href="overriding.html">Function Overloading</a>
|
||||
Next: <a href="building.html">Building a Module with Py_cpp</a>
|
||||
Next: <a href="building.html">Building a Module with BPL</a>
|
||||
Previous: <a href="special.html">Special Method and Operator Support</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
|
||||
Reference in New Issue
Block a user