55// to its suitability for any purpose.
66
77// Seems to be neccessary to suppress an ICE with MSVC
8- #include " boost/mpl/comparison/less.hpp"
8+ #include < boost/mpl/comparison/less.hpp>
99
1010#include " simple_type.hpp"
1111#include " complicated.hpp"
2121#include < boost/mpl/type_list.hpp>
2222#include < string.h>
2323
24+ // Declare some straightforward extension types
2425extern " C" void
2526dealloc (PyObject* self)
2627{
2728 PyObject_Del (self);
2829}
2930
31+ // Noddy is a type we got from one of the Python sample files
3032struct NoddyObject : PyObject
3133{
3234 int x;
@@ -50,6 +52,22 @@ PyTypeObject NoddyType = {
5052 0 , /* tp_hash */
5153};
5254
55+ // Create a Noddy containing 42
56+ extern " C" PyObject*
57+ new_noddy (PyObject* self, PyObject* args)
58+ {
59+ NoddyObject* noddy;
60+
61+ if (!PyArg_ParseTuple (args," :new_noddy" ))
62+ return NULL ;
63+
64+ noddy = PyObject_New (NoddyObject, &NoddyType);
65+ noddy->x = 42 ;
66+
67+ return (PyObject*)noddy;
68+ }
69+
70+ // Simple is a wrapper around a struct simple, which just contains a char*
5371struct SimpleObject : PyObject
5472{
5573 simple x;
@@ -73,20 +91,7 @@ PyTypeObject SimpleType = {
7391 0 , /* tp_hash */
7492};
7593
76- extern " C" PyObject*
77- new_noddy (PyObject* self, PyObject* args)
78- {
79- NoddyObject* noddy;
80-
81- if (!PyArg_ParseTuple (args," :new_noddy" ))
82- return NULL ;
83-
84- noddy = PyObject_New (NoddyObject, &NoddyType);
85- noddy->x = 42 ;
86-
87- return (PyObject*)noddy;
88- }
89-
94+ // Create a Simple containing "hello, world"
9095extern " C" PyObject*
9196new_simple (PyObject* self, PyObject* args)
9297{
@@ -101,12 +106,21 @@ new_simple(PyObject* self, PyObject* args)
101106 return (PyObject*)simple;
102107}
103108
109+ // Initial method table for the module
104110static PyMethodDef methods[] = {
105111 { " new_noddy" , new_noddy, METH_VARARGS },
106112 { " new_simple" , new_simple, METH_VARARGS },
107113 {0 , 0 , 0 , 0 }
108114};
109115
116+ //
117+ // Declare some wrappers/unwrappers to test the low-level conversion
118+ // mechanism. See boost/python/converter/source.hpp,target.hpp for a
119+ // description of how the type parameters to wrapper<> and unwrapper<>
120+ // are selected.
121+ //
122+
123+ // Wrap an int by converting it to a Python Int
110124struct int_wrapper
111125 : boost::python::converter::wrapper<int const &>
112126{
@@ -116,6 +130,7 @@ struct int_wrapper
116130 }
117131};
118132
133+ // Wrap a simple by converting it to a Simple
119134struct simple_wrapper
120135 : boost::python::converter::wrapper<simple const &>
121136{
@@ -127,6 +142,10 @@ struct simple_wrapper
127142 }
128143};
129144
145+ // wrap a mutable reference to a simple by converting it to a
146+ // Simple. Normally we wouldn't do it this way, since modifications to
147+ // the result clearly don't change the original object, but here we're
148+ // just proving that the mechanism works.
130149struct simple_ref_wrapper
131150 : boost::python::converter::wrapper<simple&>
132151{
@@ -138,6 +157,9 @@ struct simple_ref_wrapper
138157 }
139158};
140159
160+ // extract an int from a Python Int by converting it to an int. Since
161+ // int is a scalar type, we convert by-value. Since Python Ints are
162+ // immutable, there's no non-const reference converter.
141163struct native_int_unwrapper
142164 : boost::python::converter::unwrapper<int >
143165{
@@ -152,6 +174,7 @@ struct native_int_unwrapper
152174 }
153175};
154176
177+ // Extract an int from a Noddy
155178struct noddy_int_unwrapper
156179 : boost::python::converter::unwrapper<int >
157180{
@@ -166,6 +189,7 @@ struct noddy_int_unwrapper
166189 }
167190};
168191
192+ // Extract a mutable reference to an int from a Noddy.
169193struct noddy_int_ref_unwrapper
170194 : boost::python::converter::unwrapper<int &>
171195{
@@ -180,6 +204,7 @@ struct noddy_int_ref_unwrapper
180204 }
181205};
182206
207+ // Extract a mutable reference to a simple from a Simple
183208struct simple_ref_unwrapper
184209 : boost::python::converter::unwrapper<simple&>
185210{
@@ -194,6 +219,7 @@ struct simple_ref_unwrapper
194219 }
195220};
196221
222+ // Extract a const reference to a simple from a Simple
197223struct simple_const_ref_unwrapper
198224 : boost::python::converter::unwrapper<simple const &>
199225{
@@ -208,11 +234,17 @@ struct simple_const_ref_unwrapper
208234 }
209235};
210236
237+ //
238+ // Some C++ functions to expose to Python
239+ //
240+
241+ // Returns the length of s's held string
211242int f (simple const & s)
212243{
213244 return strlen (s.s );
214245}
215246
247+ // A trivial passthru function for simple objects
216248simple const & g (simple const & x)
217249{
218250 return x;
@@ -222,6 +254,7 @@ BOOST_PYTHON_MODULE_INIT(m1)
222254{
223255 PyObject* m1 = Py_InitModule (const_cast <char *>(" m1" ), methods);
224256
257+ // Create the converters; they are self-registering/unregistering.
225258 static int_wrapper wrap_int;
226259 static simple_wrapper wrap_simple;
227260 static native_int_unwrapper unwrap_int1;
@@ -233,32 +266,41 @@ BOOST_PYTHON_MODULE_INIT(m1)
233266 // These compilers will need additional converters
234267 static simple_ref_wrapper wrap_simple_ref;
235268#endif
269+
270+ // This unwrapper extracts pointers and references to the "complicated" class.
236271 static boost::python::converter::class_unwrapper<complicated> unwrap_complicated;
237272
238273 PyObject* d = PyModule_GetDict (m1);
239274 if (d == NULL )
240275 return ;
241276
277+ // Insert the extension metaclass object
242278 if (PyDict_SetItemString (
243279 d, " xclass" , (PyObject *)boost::python::object::class_metatype ()) < 0 )
244280 return ;
245281
282+ // Insert the base class for all extension classes
246283 if (PyDict_SetItemString (
247284 d, " xinst" , (PyObject *)boost::python::object::class_type ()) < 0 )
248285 return ;
249286
287+ // Expose f()
250288 if (PyDict_SetItemString (
251289 d, " f" , boost::python::make_function (f)) < 0 )
252290 return ;
253291
292+ // Expose g()
254293 if (PyDict_SetItemString (
255294 d, " g" , boost::python::make_function (g)) < 0 )
256295 return ;
257296
297+ // Expose complicated's get_n() member function. See newtest.py
298+ // for how it's used to build an extension class.
258299 if (PyDict_SetItemString (
259300 d, " get_n" , boost::python::make_function (&complicated::get_n)) < 0 )
260301 return ;
261302
303+ // Expose complicated::complicated(simple const&, int) as init1
262304 if (PyDict_SetItemString (
263305 d, " init1"
264306 , boost::python::make_constructor<
@@ -268,6 +310,7 @@ BOOST_PYTHON_MODULE_INIT(m1)
268310 ) < 0 )
269311 return ;
270312
313+ // Expose complicated::complicated(simple const&) as init2
271314 if (PyDict_SetItemString (
272315 d, " init2"
273316 , boost::python::make_constructor<
0 commit comments