diff --git a/building.html b/building.html index 96fe6e90..a25f08e4 100644 --- a/building.html +++ b/building.html @@ -34,9 +34,9 @@
© 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. + 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.
Updated: Oct 30, 2000 diff --git a/comparisons.html b/comparisons.html index 84cda747..6f6bf65a 100644 --- a/comparisons.html +++ b/comparisons.html @@ -17,28 +17,33 @@ 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 + 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. This is not entirely a - bad thing, as you can do some Pythonic things with CXX (e.g. variable - and keyword arguments) that I haven't yet figured out how to enable with - py_cpp. -
- 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. That use is also - supported by the py_cpp object wrappers. CXX claims to interoperate well - with the C++ Standard Library (a.k.a. STL) by providing iterators into - Python Lists and Dictionaries, but the claim is unfortunately - unsupportable. The problem is that in general, access to Python sequence and - mapping elements through iterators requires the use of proxy objects as - the return value of iterator dereference operations. This usage - conflicts with the basic ForwardIterator requirements in + CXX claims to interoperate well with the C++ Standard Library + (a.k.a. STL) by providing iterators into Python Lists and Dictionaries, + but the claim is unfortunately unsupportable. The problem is that in + general, access to Python sequence and mapping elements through + iterators requires the use of proxy objects as the return value of + iterator dereference operations. This usage conflicts with the basic + ForwardIterator requirements in section 24.1.3 of the standard (dereferencing must produce a reference). Although you may be able to use these iterators with some operations in some standard library implementations, it is neither guaranteed to work nor portable. + +
+ 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. +
Paul F. Dubois, the original author of CXX, has told me that what I've described is only half of the @@ -46,11 +51,11 @@ fill in the other half. Here is his response to the commentary above:
-"My intention with CXX was not to do what you are doing. It was to enable a +“My intention with CXX was not to do what you are doing. It was to enable a person to write an extension directly in C++ rather than C. I figured others had the wrapping business covered. I thought maybe CXX would provide an easier target language for those making wrappers, but I never explored -that."
-Paul Dubois +that.”
-Paul Dubois
"The problem with swig (when I used it) is that it +@@ -37,23 +37,24 @@ class world“The problem with swig (when I used it) is that it 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 this problem[sic]... IMHO overloaded functions are very important to - wrap correctly."
-Prabhu Ramachandran + wrap correctly.”
-Prabhu Ramachandran@@ -119,7 +124,7 @@ that."
-Paul Dubois GRAD is another very ambitious project aimed at generating Python wrappers for - interfaces written in "legacy languages", among which C++ is the first one + interfaces written in “legacy languages”, among which C++ is the first one implemented. Like SWIG, it aims to parse source code and automatically generate wrappers, though it appears to take a more sophisticated approach to parsing in general and C++ in particular, so it should do a much better @@ -145,9 +150,11 @@ an inheritance relationship? ExtensionClasses in Zope use the same underlying mechanism as py_cpp to support subclassing of extension types in Python, including - multiple-inheritance. Both systems rely on the same "Don - Beaudry Hack" that also inspired Don's MESS System. + Beaudry Hack” that also inspired Don's MESS System.The major differences are:
@@ -170,30 +177,27 @@ an inheritance relationship? "http://www.digicool.com/releases/ExtensionClass/MultiMapping.html">A Zope Example illustrates the differences.
- - Zope's ExtensionClasses are specifically motivated by "the need for a - C-based persistence mechanism". Py_cpp's are motivated by the desire + Zope's ExtensionClasses are specifically motivated by “the need for a + C-based persistence mechanism”. Py_cpp's are motivated by the desire to simply reflect a C++ API into Python with as little modification as possible.
- - Thus, Zope's ExtensionClasses support pickling. Currently py_cpp - ExtensionClasses do not. -
- - The following Zope restriction does not apply to py_cpp: "At most one + The following Zope restriction does not apply to py_cpp: “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 - provide extension methods but no data." + provide extension methods but no data.”
- Zope requires use of the somewhat funky inheritedAttribute (search for - "inheritedAttribute" on this page) method to access base class methods. In py_cpp, base class methods can be accessed in the usual way by writing - "
BaseClass.method". + “BaseClass.method”.- Zope supplies some creative but esoteric idioms such as - Acquisition. + Acquisition. No specific support for this is built into py_cpp.
- Zope's ComputedAttribute support is designed to be used from Python. The analogous feature of @@ -207,10 +211,10 @@ an inheritance relationship?
© 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 + 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.
- Updated: Oct 30, 2000 + Updated: Nov 25, 2000 diff --git a/enums.html b/enums.html index 44274df0..7b3b3cd8 100644 --- a/enums.html +++ b/enums.html @@ -85,9 +85,9 @@ my_class.add(python::to_python(enum_value_2), "enum_value_2");
© 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. + 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.
Updated: Nov 12, 2000 diff --git a/example1.html b/example1.html index 5ee59a03..ae643e0f 100644 --- a/example1.html +++ b/example1.html @@ -16,13 +16,15 @@ Python:
+#include <string> + namespace hello { class world { public: world(int); ~world(); - const char* get() const { return "hi, world"; } + std::string get() const { return "hi, world"; } ... }; std::size_t length(const world& x) { return std::strlen(x.get()); } diff --git a/overloading.html b/overloading.html index 9d6ae681..677052c8 100644 --- a/overloading.html +++ b/overloading.html @@ -124,7 +124,7 @@ namespace scope as Python member functions. class is found which has a matching attribute, only functions overloaded in the context of that class are candidates for overload resolution. In this sense, overload resolution mirrors the C++ mechanism, where a name - in a derived class "hides" all functions with the same name from a base + in a derived class “hides” all functions with the same name from a base class.@@ -132,13 +132,12 @@ namespace scope as Python member functions. functions are tried in the same order they were
def()ed. The first function whose signature can be made to match each argument passed is the one which is ultimately called. -
This means in particular that you cannot overload the same function on - both "int" and "float" because Python + both “int” and “float” because Python automatically converts either of the two types into the other one. - Thus, if the "float"-overload is found first, it is used - also used for arguments of type "int" as well, and the - "int"-Version of the function is never invoked. + If the “float” overload is found first, it is used + also used for arguments of type “int” as well, and the + “int” version of the function is never invoked.@@ -148,9 +147,9 @@ namespace scope as Python member functions.
© 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. + 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.
Updated: Nov 21, 2000 diff --git a/overriding.html b/overriding.html index 0b2668fe..2a1ba70b 100644 --- a/overriding.html +++ b/overriding.html @@ -12,7 +12,7 @@ In the previous example 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 behave virtually. + how to make the function behave virtually when called from C++.
Example
@@ -26,7 +26,7 @@ class world public: world(int); virtual ~world(); - virtual const char* get() const { return "hi, world"; } + virtual std::string get() const { return "hi, world"; } };
PyObject* data member that holds a reference to the
- corresponding Python object.
+ PyObject* data member that holds a
+ reference to the corresponding Python object.
- PyObject* argument in the data
- member described above.
+ PyObject* argument
+ in the data member described above.
- python::callback<return-type>::call_method() to call the
- Python override.
+ python::callback<return-type>::call_method() to call
+ the Python override.
-
- A pure virtual function with no implementation is actually a lot easier
- to deal with than a virtual function with a default implementation. First
- of all, you obviously don't need to
- supply a default implementation. Secondly, you don't need to call
+ A pure virtual function with no implementation is actually a lot easier to
+ deal with than a virtual function with a default implementation. First of
+ all, you obviously don't need to supply
+ a default implementation. Secondly, you don't need to call
def() on the extension_class<> instance
for the virtual function. In fact, you wouldn't want to: if the
- corresponding attribute on the Python class stays undefined, you'll get
- an AttributeError in Python when you try to call the
- function, indicating that it should have been implemented. For example:
+ corresponding attribute on the Python class stays undefined, you'll get an
+ AttributeError in Python when you try to call the function,
+ indicating that it should have been implemented. For example:
struct baz { diff --git a/pointers.html b/pointers.html index c2fbdade..fb133740 100644 --- a/pointers.html +++ b/pointers.html @@ -8,7 +8,9 @@Pointers -
The Problem With Pointers
+ +The Problem With Pointers
+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? @@ -32,10 +34,10 @@ converted from/to Python strings.
Can you avoid the problem?
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 +“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)
const -T*for some wrappedT, you may be able to write a "thin -converting wrapper" over those two functions as follows (Since py_cpp +T* for some wrappedT, you may be able to write a “thin +converting wrapper” over those two functions as follows (Since py_cpp convertsconst T&valuesto_pythonby copying the T into a new extension instance, Foo must have a public copy constructor): diff --git a/py_cpp.html b/py_cpp.html index f38b61cb..15bd7049 100644 --- a/py_cpp.html +++ b/py_cpp.html @@ -20,8 +20,16 @@ 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 - should simply "reflect" your C++ classes and functions into - Python. + should simply “reflect” your C++ classes and functions into + Python. The major features of py_cpp include support for: ++
+among others. +- Subclassing extension types in Python +
- Overriding virtual functions in Python +
- [Member] function Overloading +
- Automatic wrapping of numeric operators +
Supported Platforms
py_cpp has been tested in the following configurations: @@ -60,12 +68,11 @@
Py_cpp requires the boost libraries, and is - has been accepted for inclusion into the boost libraries pending "boostification" + 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).
Credits
-
- David Abrahams originated and wrote py_cpp. @@ -196,9 +203,9 @@
© 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 + 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.
- Updated: Nov 21, 2000 + Updated: Nov 25, 2000 diff --git a/under-the-hood.html b/under-the-hood.html index 7acbf37d..db3722c0 100644 --- a/under-the-hood.html +++ b/under-the-hood.html @@ -11,11 +11,14 @@ A Peek Under the Hood
-
extension_class<T>is a subclass of+ Declaring aclass_builder<T>causes the instantiation + of anextension_class<T>to which it forwards all + member function calls and which is doing most of the real work. +extension_class<T>is a subclass ofPyTypeObject, thestructwhich Python's 'C' API uses - to describe a type. An obj of - theextension_class<>becomes the Python type - object corresponding tohello::world. When we An instance of the +extension_class<>becomes the Python type object + corresponding tohello::world. When we add it to the module it goes into the module's dictionary to be looked up under the name "world".@@ -45,8 +48,8 @@ the top of your module's init function, then
defthe member functions later to avoid problems with inter-class dependencies.- Previous: function Overloading - Next: Building a module_builder with Py_cpp + Previous: Function Overloading + Next: Building a Module with Py_cpp Up: Top
© Copyright David Abrahams 2000. Permission to copy, use, modify,