2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-22 05:22:45 +00:00

Release 2000-11-06

[SVN r8151]
This commit is contained in:
Dave Abrahams
2000-11-06 05:24:07 +00:00
parent 5340194a9a
commit 1088183bae
6 changed files with 486 additions and 164 deletions

68
enums.html Normal file
View File

@@ -0,0 +1,68 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
"http://www.w3.org/TR/REC-html40/strict.dtd">
<title>
Wrapping enums
</title>
<div>
<h1>
<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). If you are satisfied
with a Python int as a way to represent your enum values, you can write some
simple <code>from_python()</code> and <code>to_python()</code> functions in
<code>namespace py::</code>
<blockquote><pre>
#ifndef PY_NO_INLINE_FRIENDS_IN_NAMESPACE // workaround GCC 2.95.2 bug
namespace py {
#endif
MyEnumType from_python(PyObject* x,
py::Type&lt;MyEnumType&gt;)
{
return static_cast&lt;MyEnum&gt;(
from_python(x, py::Type&lt;long&gt;()));
}
PyObject* to_python(MyEnumType x)
{
return to_python(static_cast&lt;long&gt;(x));
}
#ifndef PY_NO_INLINE_FRIENDS_IN_NAMESPACE
}
#endif
</pre></blockquote>
This technique defines the conversions of
<code>MyEnumType</code> in terms of the conversions for the built-in
<code>long</code> type.
You may also want to add a bunch of lines like this to your module
initialization:
<blockquote><pre>
mymodule.add(py::to_python(enum_value_1), "enum_value_1");
mymodule.add(py::to_python(enum_value_2), "enum_value_2");
...
</pre></blockquote>
You can also add these to an extension class definition:
<blockquote><pre>
my_class.add(py::to_python(enum_value_1), "enum_value_1");
my_class.add(py::to_python(enum_value_2), "enum_value_2");
...
</pre></blockquote>
<p>
&copy; Copyright David Abrahams 2000. Permission to copy, use, modify,
sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided "as is" without
express or implied warranty, and with no claim as to its suitability
for any purpose.
<p>
Updated: Nov 5, 2000
</div>

View File

@@ -35,31 +35,32 @@
</pre>
</blockquote>
<h2>Reflecting C++ Inheritance Relationships</h2>
<h2><a name="implicit_conversion">Reflecting C++ Inheritance Relationships</a></h2>
<p>
Py_cpp 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:
references to a base class are expected as arguments. The
<code>declare_base</code> member function of
<code>ClassWrapper&lt;&gt;</code> is used to establish the relationship
between base and derived classes:
<blockquote>
<pre>
#include <memory> // for std::auto_ptr<>
#include &lt;memory&gt; // for std::auto_ptr&lt;&gt;
struct Base
{
struct Base {
virtual ~Base() {}
virtual const char* name() const { return "Base"; }
};
struct Derived
{
struct Derived : Base {
Derived() : x(-1) {}
virtual const char* name() const { return "Derived"; }
int x;
};
std::auto_ptr<Base> base_factory() {
return std::auto_ptr<Base>(new Derived);
std::auto_ptr&lt;Base&gt; derived_as_base() {
return std::auto_ptr&lt;Base&gt;(new Derived);
}
const char* get_name(const Base& b) {
@@ -86,10 +87,10 @@ void initmy_module()
       py::ClassWrapper&lt;Derived&gt; derived_class(my_module, "Derived");
       derived_class.def(py::Constructor&lt;void&gt;());
// This establishes the inheritance relationship between Base and Derived
derived_class.declare_base(base_class);
<b>// Establish the inheritance relationship between Base and Derived
derived_class.declare_base(base_class);</b>
my_module.def(base_factory, "base_factory");
my_module.def(derived_as_base, "derived_as_base");
my_module.def(get_name, "get_name");
my_module.def(get_derived_x, "get_derived_x");
    }
@@ -110,12 +111,12 @@ void initmy_module()
&gt;&gt;&gt; derived = Derived()
&gt;&gt;&gt; get_name(base)
'Base'
&gt;&gt;&gt; # objects of wrapped class Derived may be passed where Base is expected
</pre><i>objects of wrapped class Derived may be passed where Base is expected</i><pre>
&gt;&gt;&gt; get_name(derived)
'Derived'
&gt;&gt;&gt; # objects of wrapped class Derived can be passed where Derived is
&gt;&gt;&gt; # expected but where type information has been lost.
&gt;&gt;&gt; get_derived_x(base_factory())
</pre><i>objects of wrapped class Derived can be passed where Derived is
expected but where type information has been lost.</i><pre>
&gt;&gt;&gt; get_derived_x(derived_as_base())
-1
</pre>
</blockquote>

View File

@@ -1,96 +1,105 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>
Overridable Virtual Functions
</title>
<h1>
<img src="c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center"
width="277" height="86">
</h1>
<h1>
Overridable Virtual Functions
</h1>
<p>
In the <a href="example1.html">previous example</a> we exposed a simple
C++ class in Python and showed that we could write a subclass. We even
redefined one of the functions in our derived class. Now we will learn
how to make the function <em>behave virtually</em>. Of course, the first
step if we want it to act like a virtual function when called from our
C++ code, is to <em>make</em> it virtual:
<blockquote>
<pre>
class world
{
...
<strong>virtual</strong> const char* get() const { return "hi, world"; }
...
};
</pre>
</blockquote>
<p>
Then we'll need a derived class<a href="#why_derived">*</a> to help us
dispatch the call to Python:
<blockquote>
<pre>
struct world_callback : hello::world
<title>Overridable Virtual Functions</title>
<img src="c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center"
width="277" height="86">
<h1>Overridable Virtual Functions</h1>
<p>
In the <a href="example1.html">previous example</a> we exposed a simple
C++ class in Python and showed that we could write a subclass. We even
redefined one of the functions in our derived class. Now we will learn
how to make the function <em>behave virtually</em>.
<h2><a name="overriding_example">Example</a></h2>
<p>In this example, it is assumed that <code>world::get()</code> is a virtual
member function:
<blockquote><pre>
class world
{
// The first argument must by a PyObject* (the corresponding Python object)
// The rest of the argument list should match the base class constructor
world_callback(PyObject* self, int x)
: world(x), // dispatch to base object
m_self(self) {} // hang onto the Python object
// Dispatch the call to Python
const char* get() const
{
// Any function arguments would go at the end of the argument list
// The return type is a template parameter
return py::Callback&lt;const char*&gt;::call_method(m_self, "get");
}
// <a name=
"default_implementation">Something Python can call</a> in case there is no override of get()
const char* default_get(hello::world* self) const
{ return self-&gt;hello::world::get(); }
private:
PyObject* m_self; // A way to hold onto the Python object
public:
   world(int);
    virtual ~world();
    <b>virtual</b> const char* get() const { return "hi, world"; }
};
</pre>
</blockquote>
<p>
Finally, we add <code>world_callback</code> to the <code>
ClassWrapper&lt;&gt;</code> declaration in our module initialization
function:
<blockquote>
<pre>
</pre></blockquote>
<p>
We'll need a derived class<a href="#why_derived">*</a> to help us
dispatch the call to Python. In our derived class, we need the following
elements:
<ol>
<li><a name="derived_1">A</a> <code>PyObject*</code> data member that holds a reference to the
corresponding Python object.
<li><a name="derived_2">A</a> constructor for each exposed constructor of the base class which stores an
additional initial <code>PyObject*</code> argument in the data
member described above.
<li><a name="derived_3">An</a> implementation of each virtual function you may wish to override in
Python which uses
<code>py::Callback&lt<i>return-type</i>&gt;::call_method()</code> to call the
Python override.
<li><a name="derived_4">For</a> each non-pure virtual function meant to be overridable from Python, a
static member function (or a free function) taking a reference or pointer to the
base type as the first parameter and which forwards any additional parameters
neccessary to the <i>default</i> implementation of the virtual function. See also
<a href="#private">this note</a> if the base class virtual function is private.
</ol>
<blockquote><pre>
struct world_callback : world
{
world_callback(PyObject* self, int x) // <a href="#derived_2">2</a>
: world(x),
m_self(self) {}
const char* get() const // <a href="#derived_3">3</a>
{ return py::Callback&lt;const char*&gt;::call_method(m_self, "get"); }
static const char* <a name= "default_implementation">default_get</a>(const hello::world& self) const // <a href="#derived_4">4</a>
{ return self.world::get(); }
private:
PyObject* m_self; // <a href="#derived_1">1</a>
};
</pre></blockquote>
<p>
Finally, we add <code>world_callback</code> to the <code>
ClassWrapper&lt;&gt;</code> declaration in our module initialization
function, and when we define the function, we must tell py_cpp about the default
implementation:
<blockquote><pre>
// Create the <a name=
"world_class">Python type object</a> for our extension class
py::ClassWrapper&lt;hello::world<strong>,world_callback&gt;</strong> world_class(hello, "world");
...
</pre>
</blockquote>
<p>
...and when we define the function, we must tell py_cpp about the default
implementation:
<blockquote>
<pre>
// Add a virtual member function
world_class.def(&amp;hello::world::get, "get", &amp;world_callback::default_get);
</pre>
</blockquote>
<p>
Now our subclass of <code>hello.world</code> behaves as expected:
<p>
<blockquote>
<pre>
world_class.def(&amp;world::get, "get", &amp;<b>world_callback::default_get</b>);
</pre></blockquote>
<p>
Now our subclass of <code>hello.world</code> behaves as expected:
<blockquote><pre>
&gt;&gt;&gt; class my_subclass(hello.world):
... def get(self):
... return 'hello, world'
...
&gt;&gt;&gt; hello.length(my_subclass())
12
</pre>
</blockquote>
</pre></blockquote>
<p>
<a name="why_derived">*</a>You may ask, "Why do we need this derived
class? This could have been designed so that everything gets done right
@@ -99,9 +108,9 @@ world_class.def(&amp;hello::world::get, "get", &amp;world_callback::default_get)
possible to expose the interface for a 3rd party library without changing
it. To unintrusively hook into the virtual functions so that a Python
override may be called, we must use a derived class.
<h2>
Pure Virtual Functions
</h2>
<h2>Pure Virtual Functions</h2>
<p>
A pure virtual function with no implementation is actually a lot easier
to deal with than a virtual function with a default implementation. First
@@ -114,14 +123,12 @@ world_class.def(&amp;hello::world::get, "get", &amp;world_callback::default_get)
function, indicating that it should have been implemented. For example:
<blockquote>
<pre>
struct baz
{
<strong>virtual</strong> void pure(int) = 0;
struct baz {
<strong>virtual</strong> int pure(int) = 0;
};
struct baz_callback
{
void pure(int x) { py::Callback&lt;void&gt;::call_method(m_self, "pure", x); }
struct baz_callback {
int pure(int x) { py::Callback&lt;int&gt;::call_method(m_self, "pure", x); }
};
extern "C"
@@ -149,18 +156,29 @@ initfoobar()
<pre>
&gt;&gt;&gt; from foobar import baz
&gt;&gt;&gt; x = baz()
&gt;&gt;&gt; x.pure()
&gt;&gt;&gt; x.pure(1)
Traceback (innermost last):
File "&lt;stdin&gt;", line 1, in ?
AttributeError: pure
&gt;&gt;&gt; class mumble(baz):
... def pure(self, z): pass
... def pure(self, x): return x + 1
...
&gt;&gt;&gt; y = mumble()
&gt;&gt;&gt; y.pure()
&gt;&gt;&gt;
</pre>
</blockquote>
&gt;&gt;&gt; y.pure(99)
100
</pre></blockquote>
<a name="private"><h2>Private Non-Pure Virtual Functions</h2></a>
<p>This is one area where some minor intrusiveness on the wrapped library is
required. Once it has been overridden, the only way to call the base class
implementation of a private virtual function is to make the derived class a
friend of the base class. You didn't hear it from me, but most C++
implementations will allow you to change the declaration of the base class in
this limited way without breaking binary compatibility (though it will certainly
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=

151
pointers.html Normal file
View File

@@ -0,0 +1,151 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
"http://www.w3.org/TR/REC-html40/strict.dtd">
<title>
Pointers
</title>
<div>
<h1>
<img width="277" height="86" id="_x0000_i1025" align="center"
src="c++boost.gif" alt= "c++boost.gif (8819 bytes)">Pointers
</h1>
<h2>The Problem With Pointers</h2>
<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?
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
referent when some C++ code deletes it?
<p>
There are a few cases in which pointers are converted automatically:
<ul>
<li>Both const- and non-const pointers to wrapped class instances can be passed
<i>to</i> C++ functions.
<li>Values of type <code>const char*</code> are interpreted as
null-terminated 'C' strings and when passed to or returned from C++ functions are
converted from/to Python strings.
</ul>
<h3>Can you avoid the problem?</h3>
<p>My first piece of advice to anyone with a case not covered above is
&quot;find a way to avoid the problem.&quot; 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 &quot;thin
converting wrapper&quot; 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):
<blockquote><pre>
const Foo* f(); // original function
const Foo& f_wrapper() { return *f(); }
...
my_module.def(f_wrapper, "f");
</pre></blockquote>
<h2>Dealing with the problem</h2>
<p>The first step in handling the remaining cases is to figure out what the pointer
means. Several potential solutions are provided in the examples that follow:
<h3>Returning a pointer to a wrapped type</h3>
<h4>Returning a const pointer</h4>
<p>If you have lots of functions returning a <code>const T*</code> for some
wrapped <code>T</code>, you may want to provide an automatic
<code>to_python</code> conversion function so you don't have to write lots of
thin wrappers. You can do this simply as follows:
<blockquote><pre>
#ifndef PY_NO_INLINE_FRIENDS_IN_NAMESPACE // work around gcc 2.95.2 bug
namespace py {
#endif
PyObject* to_python(const Foo* p) {
return to_python(*p); // convert const Foo* in terms of const Foo&
}
#ifndef PY_NO_INLINE_FRIENDS_IN_NAMESPACE
}
#endif
</pre></blockquote>
<h4>If you can't (afford to) copy the referent, or the pointer is non-const</h4>
<p>If the wrapped type doesn't have a public copy constructor, if copying is
<i>extremely</i> costly (remember, we're dealing with Python here), or if the
pointer is non-const and you really need to be able to modify the referent from
Python, you can use the following dangerous trick. Why dangerous? Because python
can not control the lifetime of the referent, so it may be destroyed by your C++
code before the last Python reference to it disappears:
<blockquote><pre>
#ifndef PY_NO_INLINE_FRIENDS_IN_NAMESPACE // work around gcc 2.95.2 bug
namespace py {
#endif
PyObject* to_python(Foo* p)
{
return py::PyExtensionClassConverters<Foo>::ptr_to_python(p);
}
PyObject* to_python(const Foo* p)
{
return to_python(const_cast<Foo*>(p));
}
#ifndef PY_NO_INLINE_FRIENDS_IN_NAMESPACE
}
#endif
</pre></blockquote>
This will cause the Foo* to be treated as though it were an owning smart
pointer, even though it's not. Be sure you don't use the reference for anything
from Python once the pointer becomes invalid, though. Don't worry too much about
the <code>const_cast&lt;&gt;</code> above: Const-correctness is completely lost
to Python anyway!
<h3>[In/]Out Parameters and Immutable Types</h3>
<p>If you have an interface that uses non-const pointers (or references) as
in/out parameters to types which in Python are immutable (e.g. int, string),
there simply is <i>no way</i> to get the same interface in Python. You must
resort to transforming your interface with simple thin wrappers as shown below:
<blockquote><pre>
const void f(int* in_out_x); // original function
const int f_wrapper(int in_x) { f(in_x); return in_x; }
...
my_module.def(f_wrapper, "f");
</pre></blockquote>
<p>Of course, [in/]out parameters commonly occur only when there is already a
return value. You can handle this case by returning a Python tuple:
<blockquote><pre>
typedef unsigned ErrorCode;
const char* f(int* in_out_x); // original function
...
#include &lt;py_cpp/objects.h&gt;
const py::Tuple f_wrapper(int in_x) {
const char* s = f(in_x);
return py::Tuple(s, in_x);
}
...
my_module.def(f_wrapper, "f");
</pre></blockquote>
<p>Now, in Python:
<blockquote><pre>
&gt;&gt;&gt; str,out_x = f(3)
</pre></blockquote>
<p>
&copy; Copyright David Abrahams 2000. Permission to copy, use, modify,
sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided "as is" without
express or implied warranty, and with no claim as to its suitability
for any purpose.
<p>
Updated: Nov 6, 2000
</div>

View File

@@ -8,77 +8,144 @@
<img src="c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277"
align="center" height="86"> py_cpp<a href="#naming_contest">*</a>
</h1>
<p>
Py_cpp is a system for quickly and easily interfacing C++ code with <a
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
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
<em>should</em> simply "reflect" your C++ classes and functions into
Python.
<h2>Supported Platforms</h2>
<p>py_cpp has been tested in the following configurations:
<ul>
<li>Against Python 1.5.2 using the following compiler/library:
<ul>
<li><a
href="http://msdn.microsoft.com/vstudio/sp/vs6sp4/dnldoverview.asp">MSVC++6sp4</a>
<li><a
href="http://msdn.microsoft.com/vstudio/sp/vs6sp4/dnldoverview.asp">MSVC++6sp4</a>/<a
href="http://www.stlport.org">STLport 4.0</a>
<li><a href="http://gcc.gnu.org/">GCC 2.95.2</a> [by <a href="mailto:koethe@informatik.uni-hamburg.de">Ullrich
Koethe</a>]
<li><a href="http://gcc.gnu.org/">GCC 2.95.2</a>/<a href="http://www.stlport.org">STLport 4.0</a>
<li>Compaq C++ V6.2-024 for Digital UNIX V5.0 Rev. 910 (an <a
href="http://www.edg.com/">EDG</a>-based compiler) with <a
href="http://www.stlport.org/beta.html">STLport-4.1b3</a> [by <a
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)
</ul>
<br>
<li>Against Python 2.0 using the following compiler/library combinations:
<ul>
<li><a
href="http://msdn.microsoft.com/vstudio/sp/vs6sp4/dnldoverview.asp">MSVC++6sp4</a> [by
<a href="mailto:aleaxit@yahoo.com">Alex Martelli</a>]
</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 &quot;boostification&quot;
(completion of the documentation, change in some naming conventions and
resolution of some namespace issues).
<h2>Credits</h2>
<p>
The source code for py_cpp, including a MSVC demo project is available <a
href="py_cpp_20001102.zip">here</a>. It has been tested against Python
1.5.2 with GCC 2.95.2 and Microsoft Visual C++ 6 sp4 using both the <a
href="http://www.stlport.org"> STLport</a> standard library implementation
<em>and</em> the library implementation which ships with the compiler. It
has also been tested against Python 2.0c1 with MSVC++ 6sp4 by Alex
Martelli. It will work with the next release of Metrowerks CodeWarrior
Pro6 (the first release has a bug that's fatal to py_cpp_). Py_cpp
requires the <a href="http://www.boost.org">Boost</a> libraries, and is
currently under formal review on <a href=
"http://www.egroups.com/list/boost">the boost mailing list</a> for
acceptance into boost.
<p>
py_cpp was originally written by David Abrahams. Ullrich Koethe supplied
an early version of the overloading support and wrote the support for
implicit conversions of arguments that have a C++ inheritance
relationship. Alex Martelli supplied the first tests against Python 2.0.
The members of the boost mailing list and the Python community supplied
invaluable early feedback. The development of py_cpp wouldn't have been
possible without the generous support of Dragon Systems/Lernout and
Hauspie, Inc.
<h2>
Table of Contents
</h2>
<ul>
<li><a href="mailto:abrahams@mediaone.net">David Abrahams</a> originated
and wrote py_cpp.
<li><a href="mailto:koethe@informatik.uni-hamburg.de">Ullrich Koethe</a>
had independently developed a similar system. When he discovered py_cpp,
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
<a href="inheritance.html#implicit_conversion">reflecting C++ inheritance
relationships</a>. He has helped to improve error-reporting from both
Python and C++, and is currently doing valuable research into <a
href="special.html#reasons">the best approach for numeric coercion</a>.
<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 development of py_cpp 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>
<h2>Table of Contents</h2>
<ol>
<li>
<a href="extending.html">A Brief Introduction to writing Python
<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 systems
for extending Python</a>
<li>
<a href="example1.html">A Simple Example Using py_cpp</a>
<li>
<a href="overriding.html">Overridable Virtual Functions</a>
<li>
<a href="overloading.html">Function Overloading</a>
<li>
<a href="inheritance.html">Inheritance</a>
<li>
<a href="special.html">Special Method Name Support</a>
<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>
</ol>
<li><a href="comparisons.html">Comparisons between py_cpp and other
systems for extending Python</a>
<li><a href="example1.html">A Simple Example Using py_cpp</a>
<li><a href="overriding.html">Overridable Virtual Functions</a>
<li><a href="overloading.html">Function Overloading</a>
<li><a href="inheritance.html">Inheritance</a>
<li><a href="special.html">Special Method Name Support</a>
<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>Advanced Topics
<ol>
<li>ClassWrapper&lt;&gt;
<li><a href="enums.html">enums</a>
<li>References
<li><a href="pointers.html">Pointers and Smart Pointers</a>
<li>Built-in Python Types
<li>Other Extension Types
<li>Templates
</ol>
</ol>
<p>
More sophisticated examples, including examples which demonstrate that
these ExtensionClasses support some of Python's "special" member
functions (e.g. <code>__getattr__(self, name)</code>), are given in
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...
<p>
Questions should be directed to <a href=
"http://www.egroups.com/list/boost">the boost mailing list</a> or to <a
href="mailto:abrahams@mediaone.net"> David Abrahams</a>, the primary
author and maintainer.
<h3>
Naming Contest
</h3>
"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

View File

@@ -1,3 +1,19 @@
======= Release =======
2000-11-06 0:22
Lots of documentation updates
added 4-argument template constructor to py::Tuple
added "add" member function to ClassWrapper<> to allow arbitrary Python
objects to be added to an extension class.
gen_all.py now generates support for n argument member functions and n+1
argument member functions at the suggestion of "Ralf W. Grosse-Kunstleve"
<rwgk@cci.lbl.gov>
Added regression tests and re-ordered declare_base calls to verify that the
phantom base class issue is resolved.
2000-11-04 17:35
Integrated Ullrich Koethe's brilliant from_python_experiment for better
@@ -49,6 +65,7 @@
Remove conflicting /Ot option from vc6_prj release build
======= Release =======
2000-11-02 17:42
Added a fix for interactions between default virtual function