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

Compare commits

...

581 Commits

Author SHA1 Message Date
nobody
b2e04cd704 This commit was manufactured by cvs2svn to create tag 'minmax'.
[SVN r22393]
2004-02-26 10:35:28 +00:00
Daniel Wallin
a9c2a95366 boost logo css class
[SVN r22352]
2004-02-21 18:42:52 +00:00
Bruno da Silva de Oliveira
29f3891a68 - Generates the unique number for UniqueInt using the hash of the filename
[SVN r22329]
2004-02-19 22:26:54 +00:00
Bruno da Silva de Oliveira
7b602ef607 - now warns that AllFromHeader is not working in all cases
[SVN r22316]
2004-02-18 22:32:58 +00:00
Bruno da Silva de Oliveira
15e555c7f1 - Fixed UniqueInt bug across different compilation units.
[SVN r22315]
2004-02-18 22:28:28 +00:00
Bruno da Silva de Oliveira
f4fb49d32f - reverted previous commit
[SVN r22313]
2004-02-18 15:33:34 +00:00
Bruno da Silva de Oliveira
89be2fb736 - no_init is now generated for abstract classes
[SVN r22312]
2004-02-18 15:27:59 +00:00
Ralf W. Grosse-Kunstleve
62f0885852 Requires: n/a removed
[SVN r22257]
2004-02-13 18:20:43 +00:00
Ralf W. Grosse-Kunstleve
355e155e69 gcc 3.4 from gcc.gnu.org still suffers from the old static initialization bug under Mac OS 10: workaround adjusted accordingly
[SVN r22255]
2004-02-13 07:10:59 +00:00
Ralf W. Grosse-Kunstleve
ae1584ff3c class_::enable_pickling() in publicized interface; tested with everything incl. VC6 and 7.0
[SVN r22254]
2004-02-13 05:32:38 +00:00
Jonathan Brandmeyer
4a7686cd33 Check rich slicing of Numeric arrays only if Numeric or numarray is
installed.


[SVN r22252]
2004-02-13 02:07:21 +00:00
Jonathan Brandmeyer
799eeb0cb8 Fix a build error on Tru64. Thanks to Ralf W. Grosse-Kunstleve for this
fix.


[SVN r22250]
2004-02-12 23:09:10 +00:00
Jonathan Brandmeyer
8452e275d0 New implementation, tests, and documentation for a PySliceObject
objectmanager.


[SVN r22192]
2004-02-07 21:38:24 +00:00
Joel de Guzman
53268000e7 small typo
[SVN r22067]
2004-01-30 06:15:32 +00:00
Dave Abrahams
52febfe3fc Improved and alphabetized news format, added Python news, updated
iterator news.

Corrections in the Python documentation


[SVN r22039]
2004-01-29 03:34:23 +00:00
Dave Abrahams
8fcfed495a Fixes for intel-linux
added <default> feature handling for specifying build defaults in requirement sets.


[SVN r22027]
2004-01-28 22:50:18 +00:00
Joel de Guzman
2dfe76b082 small typo
[SVN r22026]
2004-01-28 22:45:35 +00:00
Ralf W. Grosse-Kunstleve
11d8751d29 workaround for gcc 3.4 bug when using precompiled header support
[SVN r21715]
2004-01-14 01:37:54 +00:00
Ralf W. Grosse-Kunstleve
b03c3a29e0 previous revision (1.10) of this file restored because http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13530 is fixed
[SVN r21633]
2004-01-12 18:02:28 +00:00
Joel de Guzman
53e8982e05 fix typo
[SVN r21571]
2004-01-10 02:53:06 +00:00
Ralf W. Grosse-Kunstleve
4a30841ad8 fix for Tru64 cxx problems incl. workaround for gcc 2.96 problems; patch by David Abrahams; thanks Dave!
[SVN r21558]
2004-01-09 07:25:17 +00:00
Dave Abrahams
234ebadb8d pro9 workarounds; some ADL protection for is_xxx
[SVN r21529]
2004-01-07 14:07:21 +00:00
Dave Abrahams
11ee20fa36 Test full slicing.
[SVN r21497]
2004-01-05 12:34:25 +00:00
Dave Abrahams
440599545f Workaround for gcc-3.4 quirks
[SVN r21493]
2004-01-05 11:46:30 +00:00
Dave Abrahams
44ba088cb4 Fix problem with [:] slices on python::objects
[SVN r21472]
2004-01-04 13:41:00 +00:00
Dave Abrahams
08d3798722 .
[SVN r21449]
2004-01-02 18:34:17 +00:00
Ralf W. Grosse-Kunstleve
56ff8e438e fix use of incomplete type (Tru64 cxx diagnostic)
[SVN r21444]
2004-01-02 08:31:21 +00:00
Dave Abrahams
3590a3589d Fix 2-phase lookup bug
[SVN r21442]
2004-01-01 12:46:04 +00:00
Dave Abrahams
7674c82e1f Fix bug with (arg("x"), "y") construct.
[SVN r21437]
2003-12-31 19:20:31 +00:00
Ralf W. Grosse-Kunstleve
b93b21a7f2 work around Visual C++ 6 internal compiler errors
[SVN r21435]
2003-12-31 17:18:03 +00:00
Ralf W. Grosse-Kunstleve
f53925848c work around g++ (GCC) 3.4.0 20031230 (experimental) internal compiler error
[SVN r21432]
2003-12-31 09:37:31 +00:00
Dave Abrahams
eedc88b56a Bug fixes in property handling
[SVN r21429]
2003-12-31 00:23:52 +00:00
Ralf W. Grosse-Kunstleve
1102fec2a0 links to pickle and indexing suites
[SVN r21423]
2003-12-30 03:54:21 +00:00
Ralf W. Grosse-Kunstleve
589fefe4b9 tabs -> spaces
[SVN r21405]
2003-12-27 06:22:29 +00:00
Rene Rivera
cfc867bd18 Fix broken links.
[SVN r21404]
2003-12-27 02:37:02 +00:00
Rene Rivera
5bc28e3016 Fix broken links.
[SVN r21403]
2003-12-27 01:46:04 +00:00
Rene Rivera
23b7ccca7f Fix broken links. And some minor consistency changes.
[SVN r21402]
2003-12-27 01:31:00 +00:00
Dave Abrahams
e9d6286a1d Fix Dereferenceable concept to require pointee, and
register_ptr_to_python to require Dereferenceable.


[SVN r21327]
2003-12-18 19:25:14 +00:00
Dave Abrahams
48321857e4 consistent use of get_pointer
[SVN r21326]
2003-12-18 19:23:38 +00:00
Ralf W. Grosse-Kunstleve
156da15715 unused member function removed (to avoid Linux Intel C++ 8.0 warning)
[SVN r21278]
2003-12-16 04:14:28 +00:00
Ralf W. Grosse-Kunstleve
4a0d7965cb consolidation of workarounds for missing "not" keyword
[SVN r21276]
2003-12-15 17:55:38 +00:00
Dave Abrahams
1f522823ff gcc2 workaround
[SVN r21274]
2003-12-15 14:45:07 +00:00
Beman Dawes
6795a280fd tabs to spaces
[SVN r21080]
2003-12-02 13:32:47 +00:00
Dave Abrahams
f369e22638 Cleaner code using object instead of handle
[SVN r21018]
2003-11-30 21:12:30 +00:00
Dave Abrahams
a278da2eba correct get_pointer usage
[SVN r21017]
2003-11-30 21:10:15 +00:00
Dave Abrahams
37b2bdba79 Workaround gcc-2.x ICE
[SVN r21016]
2003-11-30 21:08:19 +00:00
Dave Abrahams
e9519db974 Make Dereferenceable use get_pointer
Re-enable map_indexing_suite iteration for vc6.


[SVN r21008]
2003-11-29 22:12:18 +00:00
Ralf W. Grosse-Kunstleve
dd7a24ebce links to newly generated tutorial sections
[SVN r20934]
2003-11-24 05:53:13 +00:00
Bruno da Silva de Oliveira
bc92a7d155 - added new "General Techniques" section
[SVN r20927]
2003-11-23 21:24:54 +00:00
Dave Abrahams
a68db84df6 * Fixed Boost.Thread jamfile to add the missing #include paths
* Modified Python testing code to use the facilities of testing.jam,
  so that it can be processed with process_jam_log

* Updated Python library tests to use a test suite

* Added Python test suite to status/Jamfile

* Added --run-all-tests option to force tests to run even when up-to-date.


Also,
boost-base.jam:

    Added some missing rule signatures

    RUN_LD_LIBRARY_PATH became LINK_LIBPATH because it was only really
    used during linking.

    Reformed the movement of path variables up the dependency graph

    Removed the defunct Run rule

    Set up generalized constants for path manipulation

darwin-tools.jam, gcc-tools.jam:

   use LINK_LIBPATH

python.jam:

   Reformed the choice of Python executable

testing.jam:

   Refactored testing code so it could be used for Python

   Now building all environment variable setup code ahead of time

   RUN_TEST became TEST_EXE


[SVN r20815]
2003-11-15 15:41:41 +00:00
Dave Abrahams
7b9bba3190 vc6 workaround
[SVN r20814]
2003-11-15 15:16:27 +00:00
Ralf W. Grosse-Kunstleve
bcec0af232 minor fix for otherwise confusing debug output
[SVN r20796]
2003-11-12 19:55:22 +00:00
Ralf W. Grosse-Kunstleve
0d437c4102 MIPSpro 7.41 workaround
[SVN r20795]
2003-11-12 19:49:18 +00:00
Raoul Gough
feff7bccd3 Fix MSVC6 duplicate comdat (LNK1179) with multiple python::range instances
[SVN r20794]
2003-11-12 16:50:17 +00:00
Ralf W. Grosse-Kunstleve
b12de3f01b additions by Niall Douglas with heavy edits by Ralf
[SVN r20780]
2003-11-10 20:39:13 +00:00
Dave Abrahams
0d108f12e4 Better error reporting for overload resolution failures, ideas thanks
to Nikolay Mladenov.


[SVN r20770]
2003-11-10 01:02:45 +00:00
Dave Abrahams
4aca2ca33b change to binary
[SVN r20689]
2003-11-06 01:14:50 +00:00
Dave Abrahams
9a967ae514 change to binary
[SVN r20688]
2003-11-06 01:13:26 +00:00
Ralf W. Grosse-Kunstleve
9481c39874 explain workaround for a bug in Apple's compiler
[SVN r20684]
2003-11-05 19:19:50 +00:00
Dave Abrahams
1e02065982 Fix Mike Rovner's warning suppression.
[SVN r20673]
2003-11-05 00:43:13 +00:00
Ralf W. Grosse-Kunstleve
1fee0da689 patch by Mike Rovner: work around gcc 3.3.1 bug (http://gcc.gnu.org/PR12163)
[SVN r20672]
2003-11-05 00:30:46 +00:00
Ralf W. Grosse-Kunstleve
c760cf8418 workaround for MIPSpro 7.3.1; old workaround for VC7.1 visible only to that particular compiler
[SVN r20668]
2003-11-04 20:20:07 +00:00
Ralf W. Grosse-Kunstleve
cdee5997af obsolete MIPSpro workaround removed
[SVN r20667]
2003-11-04 20:17:48 +00:00
Ralf W. Grosse-Kunstleve
4289280cdc Mac OS 10 answer updated
[SVN r20666]
2003-11-04 20:05:09 +00:00
Rene Rivera
962dfa17c5 Add -bind_at_load option for MacOSX Darwin build, this prevents semaphore_wait_trap erros when loaded by extensions.
[SVN r20665]
2003-11-04 18:30:37 +00:00
Ralf W. Grosse-Kunstleve
0a21aef601 fix expected output; tested with Python 2.2.1 (Redhat8) and Python 2.3 (Mac OS 10.2.8)
[SVN r20658]
2003-11-04 17:38:13 +00:00
Rene Rivera
8cbbd504cf Point to the new location for Boost.Build v1; tools/build/v1.
[SVN r20654]
2003-11-04 17:07:15 +00:00
Dave Abrahams
91b23c8367 Warning suppression thanks to Mike Rovner <mike-at-bindkey.com>
[SVN r20617]
2003-11-03 20:45:21 +00:00
Dave Abrahams
3729be263f Bug fix
[SVN r20566]
2003-10-30 18:40:37 +00:00
Dave Abrahams
ea91f4217a suppress a warning
[SVN r20555]
2003-10-29 23:16:36 +00:00
Raoul Gough
7fab3ce0b1 Add info on using gdb under Windows
[SVN r20554]
2003-10-29 21:38:06 +00:00
Dave Abrahams
ef7d675d67 bug fix for a single use of arg with no comma operator
[SVN r20533]
2003-10-29 00:46:08 +00:00
Rene Rivera
2b9d29a0fc Improve unused variable warning supperssion with multi-compiler friendly code.
[SVN r20466]
2003-10-24 01:19:16 +00:00
Bruno da Silva de Oliveira
95b95d012c - Fixed bug where a class would appear more than one in the generated code.
[SVN r20464]
2003-10-23 22:56:33 +00:00
Rene Rivera
4af7d5bca7 Remove unused var warning on non-debug compilation.
[SVN r20463]
2003-10-23 20:15:50 +00:00
Rene Rivera
d879eb235f Add install definitions for new common install configuration.
[SVN r20409]
2003-10-19 19:52:56 +00:00
Dave Abrahams
4f129d035b Bug fix, thanks to Nicolas LELONG, nlelong-at-mgdesign.org for the report.
[SVN r20401]
2003-10-17 14:13:48 +00:00
Dave Abrahams
7a354c4ff4 Warning suppression for GCC.
[SVN r20396]
2003-10-15 23:19:48 +00:00
Dave Abrahams
364826b3b3 Include @group directives for Synopsis
[SVN r20364]
2003-10-13 21:04:11 +00:00
Raoul Gough
e9b308da46 Use msvc_typeid only if _MSV_VER is set, to avoid problems with Intel compiler on Linux
[SVN r20340]
2003-10-10 14:55:13 +00:00
Dave Abrahams
94cfa2602f Fix typo
[SVN r20324]
2003-10-09 14:15:20 +00:00
Bruno da Silva de Oliveira
3533bd0504 no message
[SVN r20266]
2003-10-06 19:10:50 +00:00
Bruno da Silva de Oliveira
1a51a7df9e - added missing <boost/python/return_arg.hpp>
[SVN r20257]
2003-10-04 21:44:24 +00:00
Dave Abrahams
615be89951 Support for logical negation operator via __nonzero__
[SVN r20256]
2003-10-04 15:40:09 +00:00
Dave Abrahams
912ca36a1f fixed broken link
[SVN r20255]
2003-10-04 12:06:19 +00:00
Dave Abrahams
fba93805dc Work with gcc2
[SVN r20168]
2003-09-23 23:57:23 +00:00
Dave Abrahams
96d66f4624 Correct integral constant overflow
[SVN r20136]
2003-09-21 18:49:04 +00:00
Dave Abrahams
c3bae63e41 Fix const-correctness problem
[SVN r20135]
2003-09-21 17:24:37 +00:00
Bruno da Silva de Oliveira
6c22aceabc - added return_by_value
[SVN r20127]
2003-09-21 02:07:07 +00:00
Dave Abrahams
92a77dfe7f Implemented injected constructors.
Eliminated _DEBUG redefinition warning for CWPro8.


[SVN r20126]
2003-09-21 01:35:19 +00:00
Bruno da Silva de Oliveira
4f2dbeda28 bugs in Enum and export_values option
[SVN r20121]
2003-09-19 23:07:14 +00:00
Dave Abrahams
bec2de08fe Use make_function uniformly to build callable objects.
Fix wstring support so it doesn't break gcc2.95.x, which has no wstring.

Modify CallPolicies protocol so it can safely adjust the argument tuple.


[SVN r20090]
2003-09-17 21:36:53 +00:00
Raoul Gough
db192e1e01 Remove incref of Py_None in make_nurse_and_patient - inc already done in detail::none()
[SVN r20079]
2003-09-16 17:31:06 +00:00
Dave Abrahams
454654a9cc Try to ward off personal emails
[SVN r20041]
2003-09-12 20:08:05 +00:00
Dave Abrahams
1018bc56eb put newlines in the list of links
[SVN r20037]
2003-09-12 14:54:34 +00:00
Dave Abrahams
f920dc87d0 Added std::wstring conversion support
Added std::out_of_range => Python IndexError exception conversion,
thanks to Raoul Gough


[SVN r20027]
2003-09-11 19:19:55 +00:00
Dave Abrahams
8b97caae46 Warn about duplicate to-python converters and show the name of the
offending type.


[SVN r20023]
2003-09-11 15:09:11 +00:00
Dave Abrahams
3b74aab818 add pyfinalize safety
[SVN r20022]
2003-09-11 11:07:05 +00:00
Dave Abrahams
e78b4939b3 Added new str constructors which take a range of characters, allowing
strings containing nul ('\0') characters.


[SVN r20006]
2003-09-11 02:57:24 +00:00
Bruno da Silva de Oliveira
621b5fc2db - added INTERFACE_FILE
[SVN r20005]
2003-09-10 21:55:50 +00:00
Dave Abrahams
6ada069d5a Update for cross-project capability
[SVN r20002]
2003-09-10 16:08:41 +00:00
Joel de Guzman
50db384be1 Used BOOST_WORKAROUND
[SVN r19980]
2003-09-09 13:13:44 +00:00
Dave Abrahams
ae7225ae83 Updates for cross-project dependencies
[SVN r19977]
2003-09-09 03:14:01 +00:00
Dave Abrahams
911ba333a2 restored python test drivers
[SVN r19976]
2003-09-09 02:55:39 +00:00
Dave Abrahams
5cd8cce531 Set up BOOST_ROOT before import python has a chance to use it.
[SVN r19974]
2003-09-09 02:42:17 +00:00
Dave Abrahams
6a2a76cea9 Use new cross-project feature
[SVN r19969]
2003-09-08 19:36:06 +00:00
Dave Abrahams
7a9a3d30c9 Use the import rule
[SVN r19968]
2003-09-08 17:38:49 +00:00
Joel de Guzman
034ca4d5eb mscv workaround
[SVN r19962]
2003-09-08 12:56:33 +00:00
Dave Abrahams
00e3fa32fb Fix typo
[SVN r19949]
2003-09-07 19:45:21 +00:00
Dave Abrahams
0133bdfbe3 Removed unused ConverterGenerators arguments.
Updated arg_from_python<T> so that its operator() is nullary -- it
already gets everything it needs in its constructor.


[SVN r19948]
2003-09-07 19:44:44 +00:00
Dave Abrahams
e563def5ba Update documentation for the use of function objects.
[SVN r19947]
2003-09-07 18:03:20 +00:00
Dave Abrahams
b3910f4e4d Support for wrapping function objects and classes which use virtual
inheritance.  Completely killed off member_function_cast!


[SVN r19945]
2003-09-07 16:56:05 +00:00
Bruno da Silva de Oliveira
4a7b8fe839 - Wrapper for protected and private pure virtual functions are now generated
[SVN r19922]
2003-09-04 22:47:04 +00:00
Joel de Guzman
fc56544da4 added note to use bjam as the preferred build tool
[SVN r19889]
2003-09-01 03:12:34 +00:00
Dave Abrahams
c839d25722 Add module_tail for JIT debugging
[SVN r19863]
2003-08-29 19:42:39 +00:00
Dave Abrahams
c6b5ecbbdb Update for select_holder changes
[SVN r19862]
2003-08-29 19:03:14 +00:00
Joel de Guzman
d3473afa23 Take 2
[SVN r19805]
2003-08-27 12:10:49 +00:00
Joel de Guzman
379b28eb85 Some more tweaks
[SVN r19803]
2003-08-27 10:18:37 +00:00
Joel de Guzman
7f5bd33ead Tweaks
[SVN r19802]
2003-08-27 10:14:14 +00:00
Joel de Guzman
eef6fb9891 def_visitor linked in the reference
[SVN r19801]
2003-08-27 10:09:08 +00:00
Joel de Guzman
4a7f52ab2c Initial commit of def_visitor doc
[SVN r19800]
2003-08-27 10:00:23 +00:00
Bruno da Silva de Oliveira
10b249a162 - Using the new Boost.Python facility for wrapping pure virtual functions
[SVN r19792]
2003-08-26 23:24:02 +00:00
Dave Abrahams
5fc5fce663 removed intro text
[SVN r19790]
2003-08-26 15:49:50 +00:00
Dave Abrahams
f00fe3c0b1 Added reference to TODO list
[SVN r19789]
2003-08-26 15:48:36 +00:00
Dave Abrahams
3047d51613 revised, ReST-ized HTML-ized
[SVN r19788]
2003-08-26 15:47:41 +00:00
Dave Abrahams
f9f7146960 revised, ReST-ized HTML-ized
[SVN r19787]
2003-08-26 15:42:51 +00:00
Ralf W. Grosse-Kunstleve
ca9dc3103a print running... Done.
[SVN r19785]
2003-08-26 13:19:51 +00:00
Ralf W. Grosse-Kunstleve
c03afa379c print Done before sys.exit; this allows us to detect fatal crashes like segmentation faults on import
[SVN r19784]
2003-08-26 13:11:51 +00:00
Ralf W. Grosse-Kunstleve
cbacc98e3f MIPSpro workaround
[SVN r19783]
2003-08-26 12:52:21 +00:00
Dave Abrahams
84daf14f1b Added missing #includes
[SVN r19782]
2003-08-26 11:45:47 +00:00
Dave Abrahams
4af28b2a46 Added missing #includes
[SVN r19778]
2003-08-26 02:25:33 +00:00
Bruno da Silva de Oliveira
acbc01933c - Fixed a bug where the code for a virtual method wrapper defined inside a Pyste file was not being declared in the generated code
[SVN r19776]
2003-08-26 00:43:09 +00:00
Dave Abrahams
7ec78eecbd Implemented pure_virtual(...)
[SVN r19774]
2003-08-25 18:44:26 +00:00
Dave Abrahams
87c5e37f5e vc6 workaround for nested enums
[SVN r19773]
2003-08-25 18:41:26 +00:00
Dave Abrahams
d02959e3ed Remove cwpro7 workarounds; simplified select_holder
[SVN r19772]
2003-08-25 18:41:02 +00:00
Dave Abrahams
b844d8b750 Refactoring and cleanups
[SVN r19770]
2003-08-25 18:38:39 +00:00
Bruno da Silva de Oliveira
0a3010b29f no message
[SVN r19761]
2003-08-23 20:53:33 +00:00
Bruno da Silva de Oliveira
2b380d03c9 - Make the cache files be rebuilt only when the declarations' version changes, instead o pyste's version
[SVN r19759]
2003-08-23 19:18:52 +00:00
Bruno da Silva de Oliveira
3f70253a3f - Fixed bug where Include was not writing the #include in some situations
- Rebuild cache files if pyste version changes


[SVN r19757]
2003-08-23 17:06:37 +00:00
Dave Abrahams
165e294298 Fix #ifdef
[SVN r19745]
2003-08-23 11:41:00 +00:00
Ralf W. Grosse-Kunstleve
f7c9f45508 simple fix for MIPSpro after a long struggle; thanks to Stephen Adamczyk and John Spicer at EDG!
[SVN r19724]
2003-08-21 21:27:38 +00:00
Joel de Guzman
af2a924301 more workaround fixes for VC6 linker bug
[SVN r19714]
2003-08-20 13:15:41 +00:00
Joel de Guzman
3981e83de5 workaround MSVC linker bug
[SVN r19713]
2003-08-20 12:07:48 +00:00
Bruno da Silva de Oliveira
88b9721e3f - Fixed bug related to bases<> template generation in the new system
[SVN r19700]
2003-08-20 01:40:43 +00:00
Joel de Guzman
4946af1448 Map indexing fix for VC6.5
[SVN r19699]
2003-08-19 20:32:56 +00:00
Dave Abrahams
9959dcfa49 Always #include prefix.h first of all.
[SVN r19694]
2003-08-19 15:44:30 +00:00
Joel de Guzman
cfb13fad22 fix for wrapping vector<bool>
[SVN r19692]
2003-08-19 03:28:53 +00:00
Joel de Guzman
4e3f3a052d chaned struct def_visitor; to class def_visitor;
[SVN r19691]
2003-08-19 02:23:16 +00:00
Bruno da Silva de Oliveira
dc7ae9ed20 - removed "header_code", since we already have Include().
[SVN r19670]
2003-08-17 21:11:07 +00:00
Bruno da Silva de Oliveira
929badf4c6 Added support for insertion of user code in the generated code
[SVN r19664]
2003-08-17 19:35:00 +00:00
Bruno da Silva de Oliveira
c4a3f2c04f no message
[SVN r19652]
2003-08-16 21:11:50 +00:00
Bruno da Silva de Oliveira
a933e458b3 - Fixed a bug in the pure virtual functions
[SVN r19648]
2003-08-16 19:13:45 +00:00
Bruno da Silva de Oliveira
06b8320815 - Added exception specifiers (patch by Gottfried).
[SVN r19645]
2003-08-16 18:21:44 +00:00
Dave Abrahams
7f3aceafd2 Fix public/private error.
[SVN r19636]
2003-08-16 13:56:52 +00:00
Dave Abrahams
da5979931c class.hpp, object/select_holder.hpp, object/pointer_holder.hpp -
fix a problem which was causing value_holder<T> to be instantiated
   on abstract classes.  Now we compute the held_type at an outer
   level thereby avoiding the inner instantiation.

object_core.hpp -

   workarounds for GCC 2.x bugs

suite/indexing/detail/indexing_suite_detail.hpp -

   workaround for a CWPro8 bug


[SVN r19635]
2003-08-16 13:48:34 +00:00
Dave Abrahams
d8c7e75095 Fix the fix... again!
[SVN r19617]
2003-08-15 03:45:34 +00:00
Joel de Guzman
187506c97f added map value type (std::pair) wrapper to map_indexing_suite.hpp
[SVN r19616]
2003-08-15 03:03:27 +00:00
Joel de Guzman
145c6d1e4f moved map value type (std::pair) wrapper to map_indexing_suite.hpp
[SVN r19615]
2003-08-15 03:01:32 +00:00
Dave Abrahams
e2973f27f9 Fix the fix ;-)
[SVN r19613]
2003-08-14 22:53:30 +00:00
Dave Abrahams
976b8180ae Workaround a VC7 bug with nested enums
[SVN r19611]
2003-08-14 22:48:01 +00:00
Joel de Guzman
37acf41d43 Added map_indexing_suite test
[SVN r19600]
2003-08-14 15:05:02 +00:00
Joel de Guzman
6f26778491 Initial commit map_indexing_suite tests
[SVN r19599]
2003-08-14 15:04:25 +00:00
Joel de Guzman
834d815c87 mapping suite update
[SVN r19598]
2003-08-14 15:03:14 +00:00
Joel de Guzman
57e58c445b Tweaks to accomodate map_indexing_suite
[SVN r19588]
2003-08-14 12:14:25 +00:00
Joel de Guzman
8a1a8342d6 Initial commit map_indexing_suite
[SVN r19587]
2003-08-14 12:13:15 +00:00
Joel de Guzman
fa70ddc2c5 Preparing for std::map suite
[SVN r19566]
2003-08-12 21:21:47 +00:00
Joel de Guzman
8ca32bb494 Minor tweak in preparation for map_indexing_suite.hpp
[SVN r19565]
2003-08-12 18:36:55 +00:00
Joel de Guzman
f6c82eba0c changed def_arg to def_visitor
[SVN r19564]
2003-08-12 18:35:00 +00:00
Joel de Guzman
344044a315 updated the include path to vector_indexing_suite.hpp
[SVN r19563]
2003-08-12 18:13:19 +00:00
Joel de Guzman
b10805dc4c moved to new "suite" directory
[SVN r19562]
2003-08-12 18:09:21 +00:00
Joel de Guzman
07f397e2ed Moved to new "suite" directory
[SVN r19561]
2003-08-12 18:07:11 +00:00
Dave Abrahams
054dc439d2 Workaround msvc bug
[SVN r19553]
2003-08-12 14:17:52 +00:00
Dave Abrahams
5008dcbdd4 Make sure the class object and cast relationships are registered for
virtual function dispatch classes.


[SVN r19543]
2003-08-12 04:36:42 +00:00
Dave Abrahams
9c6650963f Use def_visitor to simplify class def(...) handling.
Workarounds for intel6 and vc6.


[SVN r19533]
2003-08-11 14:56:30 +00:00
Dave Abrahams
d482d57689 added properties tests
[SVN r19532]
2003-08-11 14:30:04 +00:00
Dave Abrahams
edf6516085 Python 2.3 compatibility.
[SVN r19530]
2003-08-11 11:07:28 +00:00
Dave Abrahams
957ac66e14 Added missing #include
Use BOOST_EXPLICIT_TEMPLATE_TYPE


[SVN r19529]
2003-08-11 02:21:34 +00:00
Dave Abrahams
07ce84c4e7 Repair bugs introduced during previous workaround
[SVN r19526]
2003-08-11 02:01:15 +00:00
Bruno da Silva de Oliveira
918636ff03 - Fixed a bug where in some classes the virtual methods were being definied incorrectly
[SVN r19525]
2003-08-10 23:21:25 +00:00
Dave Abrahams
83a6adbfa9 Added properties news item
changed the name of the static property class to
Boost.Python.StaticProperty (was Boost.Python.Class).


[SVN r19521]
2003-08-10 22:56:58 +00:00
Dave Abrahams
fcbc1d562f Added properties unit test from Roman Yakovenko
<romany-at-actimize.com>.


[SVN r19520]
2003-08-10 22:51:51 +00:00
Dave Abrahams
c3b4b58075 Extended CWPro8 overload ambiguity workaround to cover make_setter as
well as make_getter.


[SVN r19519]
2003-08-10 22:50:38 +00:00
Bruno da Silva de Oliveira
568b62a8a4 - Little bug where the memory cache was not being used
[SVN r19517]
2003-08-10 21:51:28 +00:00
Bruno da Silva de Oliveira
da34e7f507 - Abstract methods fix
- converts \ to / on windows


[SVN r19516]
2003-08-10 21:47:50 +00:00
Joel de Guzman
a0c31b47e5 refactored code + cleanup
[SVN r19508]
2003-08-10 15:20:10 +00:00
Joel de Guzman
5fb677c0c5 initial commit of container utils
[SVN r19507]
2003-08-10 15:19:23 +00:00
Bruno da Silva de Oliveira
168476382a - incremental code and some fixes
[SVN r19499]
2003-08-09 21:18:12 +00:00
Bruno da Silva de Oliveira
7fa6a29814 no message
[SVN r19498]
2003-08-09 20:57:04 +00:00
Bruno da Silva de Oliveira
f2b51da0ab - Fix a bug where a declaration was appearing more than once in an intermediate class in an hierarchy not fully-exported
[SVN r19489]
2003-08-08 02:56:04 +00:00
Joel de Guzman
53726746b8 Clean-up, refactored and added NoSlice option.
[SVN r19488]
2003-08-07 17:16:07 +00:00
Joel de Guzman
fe0b59f559 some trivial fixes.
[SVN r19485]
2003-08-07 12:29:54 +00:00
Joel de Guzman
c014dee6dc Fixed no proxy handling for containers of primitive types.
[SVN r19484]
2003-08-07 08:45:57 +00:00
Joel de Guzman
90c69d961e Added named visitor .def facility.
[SVN r19483]
2003-08-07 03:07:20 +00:00
Dave Abrahams
342f7db678 Workaround vc7.1 typeid problem with cv-qualified arrays.
[SVN r19474]
2003-08-06 13:51:03 +00:00
Joel de Guzman
9eb704f85a fixed iteration scheme and added append and extend methods
[SVN r19469]
2003-08-06 08:06:09 +00:00
Dave Abrahams
7754a91929 Update docs for static data support.
[SVN r19462]
2003-08-05 13:41:21 +00:00
Dave Abrahams
e4dc639e54 Allow mutating operations on self for all operators
[SVN r19454]
2003-08-05 03:15:37 +00:00
Ralf W. Grosse-Kunstleve
5d90101671 workaround for MIPSpro, thanks to John Spicer
[SVN r19453]
2003-08-05 03:03:49 +00:00
Ralf W. Grosse-Kunstleve
437fb70852 Tru64 cxx requires X::operator!=
[SVN r19450]
2003-08-05 00:49:33 +00:00
Dave Abrahams
d598404c48 initial commit
[SVN r19449]
2003-08-04 23:52:01 +00:00
Joel de Guzman
32c7088600 added missing typename and include file
[SVN r19448]
2003-08-04 23:34:52 +00:00
Joel de Guzman
ccede29816 added missing line feed at end of source
[SVN r19447]
2003-08-04 23:34:02 +00:00
Ralf W. Grosse-Kunstleve
b55b7e2f7b workaround for Mac OS 10 gcc 3.3 static initialization bug
[SVN r19446]
2003-08-04 22:09:16 +00:00
Ralf W. Grosse-Kunstleve
9217a6a253 avoid (incorrect) Tru64 cxx 6.5.1 warning
[SVN r19445]
2003-08-04 20:54:07 +00:00
Dave Abrahams
07c1319b99 Added the new arg class from
"nickm-at-sitius.com" (Nikolay Mladenov) which supplies the
ability to wrap functions that can be called with ommitted
arguments in the middle.


[SVN r19441]
2003-08-04 17:46:48 +00:00
Dave Abrahams
714b5dc26e missing checkin
[SVN r19439]
2003-08-04 17:36:49 +00:00
Joel de Guzman
1f715958f9 Fixed get_slice
[SVN r19421]
2003-08-04 05:09:23 +00:00
Joel de Guzman
0922aca873 Better usage of handle<>.
[SVN r19420]
2003-08-04 03:24:41 +00:00
Joel de Guzman
30ec6181b5 Fixed negative ref count bug
[SVN r19419]
2003-08-04 02:36:47 +00:00
Dave Abrahams
b28d586612 Move assignment operator inline as a workaround for a vc7 bug.
[SVN r19416]
2003-08-03 14:19:09 +00:00
Dave Abrahams
f48aacf477 added internals
[SVN r19390]
2003-07-31 18:03:17 +00:00
Dave Abrahams
bfa868a440 Workarounds for VC6 bugs
[SVN r19389]
2003-07-31 15:56:10 +00:00
Dave Abrahams
f01ff3a277 Prune #includes
[SVN r19382]
2003-07-31 01:04:51 +00:00
Dave Abrahams
d88e6bf688 object_core.hpp - use detail/is_xxx to generate template identifiers
object_operators.hpp - use SFINAE to prevent ADL from finding
        generalized operators inappropriately


[SVN r19377]
2003-07-30 23:48:06 +00:00
Dave Abrahams
a3cdacd088 Bug fix -- we weren't handling NULL keywords dictionaries in raw_function
[SVN r19359]
2003-07-30 11:34:50 +00:00
Joel de Guzman
81d99c855f Minor tweaks
[SVN r19335]
2003-07-29 04:47:34 +00:00
Joel de Guzman
5cd110f625 Comments from Dave + Editing + Proof reading and stuff
[SVN r19334]
2003-07-29 04:30:37 +00:00
Joel de Guzman
416895ff30 linked in the indexing suite documentation
[SVN r19315]
2003-07-26 05:49:57 +00:00
Joel de Guzman
e41abb6e92 Initial commit of indexing suite documentation
[SVN r19314]
2003-07-26 05:48:59 +00:00
Joel de Guzman
a6440a3fa6 Minor tweaks
[SVN r19313]
2003-07-26 05:47:11 +00:00
Joel de Guzman
2dece7ecaf added __iter__ and __contains__
[SVN r19311]
2003-07-26 01:50:35 +00:00
Dave Abrahams
7aae525587 Added RationalDiscovery
[SVN r19300]
2003-07-24 16:38:23 +00:00
Ralf W. Grosse-Kunstleve
ac5314093b fixing some trivial bugs (missing or misplaced typename); work around gcc 3.2 bug
[SVN r19299]
2003-07-24 15:07:05 +00:00
Ralf W. Grosse-Kunstleve
1524fb9fa9 flotsam removed
[SVN r19297]
2003-07-24 13:51:06 +00:00
Joel de Guzman
957549460b Initial Commit of Indexing Suite
[SVN r19296]
2003-07-24 12:02:57 +00:00
Joel de Guzman
3b33f54fb8 Added generic visitation mechanism.
[SVN r19288]
2003-07-24 01:44:18 +00:00
Ralf W. Grosse-Kunstleve
42ab6b6b66 unused variable removed (to avoid MIPSpro warning)
[SVN r19287]
2003-07-23 19:00:55 +00:00
Dave Abrahams
f59a5bbabc Stop printing return types in error messages.
[SVN r19286]
2003-07-23 17:04:05 +00:00
Dave Abrahams
0be371d747 Added cross-module exception test
[SVN r19282]
2003-07-23 15:17:03 +00:00
Dave Abrahams
2b52210291 remove (again!) extra diagnostic info
[SVN r19281]
2003-07-23 14:14:00 +00:00
Dave Abrahams
96a7bce78e Give feedback about the name and namespace of functions in error messages.
[SVN r19280]
2003-07-23 13:08:59 +00:00
Dave Abrahams
c1e1ea697c Added Metafaq link
[SVN r19278]
2003-07-23 11:43:06 +00:00
Dave Abrahams
874d6ebf2c Kill off nasty diagnostic printing.
[SVN r19277]
2003-07-23 11:11:56 +00:00
Dave Abrahams
77f5eb703c Attempt to work around a GCC EH problem by sticking a virtual function
in error_already_set and defining it in the library.

Removed some flotsam


[SVN r19274]
2003-07-23 03:00:48 +00:00
Dave Abrahams
af53ae8329 Implemented better error reporting for argument match errors.
[SVN r19271]
2003-07-23 01:31:34 +00:00
Dave Abrahams
8f76b8880e Remove bad #includes
[SVN r19269]
2003-07-22 23:55:09 +00:00
Dave Abrahams
fa398734be initial commit
[SVN r19267]
2003-07-22 23:53:06 +00:00
Dave Abrahams
362d20a8c7 Fixed editing error
[SVN r19265]
2003-07-22 20:12:39 +00:00
Dave Abrahams
6a33b8aeeb Implemented better error reporting for argument match errors.
[SVN r19264]
2003-07-22 20:12:07 +00:00
Dave Abrahams
d4e06ac436 Preparation for delivering nicely-formatted error messages in
Boost.Python.  The major change is that, instead of being
boost::function2<PyObject*,PyObject*,PyObject*>, py_function is now a
runtime-polymorphic wrapper for compile-time polymorphic
behavior (just like function) of our own which carries more
information/behaviors.  In particular, you can retrieve an array of
c-strings describing the types in the function signature.
Additionally, the minimum and maximum arity are stored in the
py_function object instead of in the 'function' object which wraps it.

* data_members.hpp -

     Adjustments for the new py_function.  Workarounds for CodeWarrior
     Pro 8.3 bugs in function template argument deduction with
     pointers-to-members.

* has_back_reference.hpp, test/back_reference.cpp,
  test/select_holder.cpp -

     Updated to follow the metafunction protocol

* init.hpp, detail/defaults_gen.hpp -

     Make Keywords a more-specific type in function signatures to
     prevent string literals that show up as char[N] from binding to
     the wrong argument (at least Intel 7.1 for Windows does this).

* make_function.hpp -

     Adjustments for the new py_function.  Arities are now computed
     by caller<>.

* opaque_pointer_converter.hpp, type_id.hpp -

     Use BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS facilities;
     generate specializations that all compilers can handle.

* raw_function.hpp -

     Adjustments for the new py_function.

* caller.hpp -

     Added arity and signature type name reporting.

* detail/config.hpp

     Enable __declspec(dllexport) for Cygwin, thereby fixing the
     recent horrible Cygwin linking problems.


* detail/msvc_typeinfo.hpp -

     Always pass boost::type<T>* explicitly, thereby working around
     incompatible notions of how to specialize function templates with
     default arguments on various compilers.

*   object/function.hpp
  , object/function_handle.hpp
  , object/function_object.hpp
  , object/function_object.cpp

     Adjustments for the new py_function.  Arities are carried by
     py_function.

* object/iterator.hpp, object/iterator.cpp

     Adjustments for the new py_function; we have to compute a
     signature of types to construct it with.

* object/py_function.hpp

     Removed dependency on boost::function; see the comment at the
     top of this entry for more details.

* object/select_holder.hpp

     Clean up to more closely follow MPL idioms.

* test/Jamfile -

     Adjust the embedding test for the new Cygwin use of declspec.
     Update bases and pointee tests with missing properties.

* test/input_iterator.cpp -

     Updates for the new iterator adaptors.

* test/opaque.py -

     Add Python encoding comment to suppress PendinDeprecationWarning
     with recent Python builds.

* test/str.cpp

     Pass a Python long instead of a float to string.expandtabs,
     suppressing a PendinDeprecationWarning with recent Python builds.

* libs/utility/counting_iterator_example.cpp

     Borland workaround

* libs/utility/indirect_iterator_example.cpp

     const-correctness fix.

*


[SVN r19247]
2003-07-22 00:06:41 +00:00
Dave Abrahams
817dcd37e0 Get Cygwin linking again
User-readable type name printing for GCC


[SVN r19236]
2003-07-21 02:14:58 +00:00
Dave Abrahams
25bfd3c50f Suppress a GCC 2.x ICE
[SVN r19235]
2003-07-21 02:12:04 +00:00
Dave Abrahams
b13c902fb0 * added return_arg policy from Nikolay Mladenov
* removed duplication from reference.html

* improved automatic redirection messages


[SVN r19226]
2003-07-19 23:49:06 +00:00
Dave Abrahams
c95ef44b02 Added Kig
[SVN r19154]
2003-07-16 15:40:27 +00:00
Bruno da Silva de Oliveira
162727590c - moved register_ptr_to_python up one level.
[SVN r19123]
2003-07-15 01:05:07 +00:00
Vladimir Prus
7e159844fb Update for current Boost.Build V2.
[SVN r19037]
2003-07-11 06:04:35 +00:00
Dave Abrahams
787b79cc2c Added NeuraLab
[SVN r18979]
2003-07-08 13:10:59 +00:00
Bruno da Silva de Oliveira
b77652b499 - fixed staticmethod bug
- fixed hierarchies bug when using AllFromHeader


[SVN r18971]
2003-07-07 20:00:40 +00:00
Bruno da Silva de Oliveira
0c8444b8ed - fixed bug of --multiple
- new function: hold_with_shared_ptr
- SPECIALIZE_TYPE_ID bug


[SVN r18969]
2003-07-07 19:00:52 +00:00
Bruno da Silva de Oliveira
3e6ee799ba - --multiple now generates one cpp per pyste file.
[SVN r18945]
2003-07-06 01:16:27 +00:00
Bruno da Silva de Oliveira
dd14ccb115 - --multiple now generates one cpp per pyste file.
[SVN r18944]
2003-07-06 01:12:26 +00:00
Bruno da Silva de Oliveira
ba0fcd27c3 - Various bug fixes
- Changed the internal code to the way it was


[SVN r18941]
2003-07-04 22:47:27 +00:00
Bruno da Silva de Oliveira
d476e67067 - Fixed "char**" bug
- Lots of internal changes: phase 1 of Meta-Programming complete.


[SVN r18919]
2003-07-03 00:00:23 +00:00
Bruno da Silva de Oliveira
4588f5e9ab no message
[SVN r18884]
2003-06-29 17:47:45 +00:00
Bruno da Silva de Oliveira
68f54d364b - register_ptr_to_python addition
[SVN r18880]
2003-06-27 18:34:25 +00:00
Dave Abrahams
7dba18e7b9 Test that shared_ptr<Derived> can be converted to shared_ptr<Base>
[SVN r18851]
2003-06-20 22:57:37 +00:00
Dave Abrahams
67b265fe96 Remove duplicated sections
[SVN r18835]
2003-06-18 12:22:28 +00:00
Bruno da Silva de Oliveira
8289269a86 *** empty log message ***
[SVN r18828]
2003-06-18 00:05:01 +00:00
Bruno da Silva de Oliveira
9f711ed821 - Changed "no_override" to "final"
[SVN r18826]
2003-06-17 23:25:16 +00:00
Bruno da Silva de Oliveira
73e2ab5125 - Added a new test exercising the new automatic inheritation
[SVN r18815]
2003-06-17 01:56:45 +00:00
Bruno da Silva de Oliveira
7ea2ab1672 - If you export a derived class without exporting its base classes, the derived class will explicitly export the bases's methods and attributes. Before, if you were interested in the bases's methods, you had to export the base classes too.
- Added a new function, no_override. When a member function is specified as "no_override", no virtual wrappers are generated for it, improving performance and letting the code more clean.

- There was a bug in which the policy of virtual member functions was being ignored (patch by Roman Sulzhyk).


[SVN r18814]
2003-06-17 01:34:26 +00:00
Bruno da Silva de Oliveira
c821e903f8 Added tests for linux.
[SVN r18809]
2003-06-16 20:36:36 +00:00
Ralf W. Grosse-Kunstleve
54db04521a MIPSpro workaround
[SVN r18744]
2003-06-09 13:10:34 +00:00
Bruno da Silva de Oliveira
91fdecd76f - Changed the filename of one of the doc files to limit it to 32 chars.
[SVN r18709]
2003-06-08 22:51:37 +00:00
Dave Abrahams
f140a74a13 Added MinGW tips
[SVN r18695]
2003-06-06 11:18:34 +00:00
Bruno da Silva de Oliveira
4854a2a81b - Added another entry, about ESSS.
[SVN r18685]
2003-06-06 00:04:51 +00:00
Bruno da Silva de Oliveira
d94bb65006 - Major improvements in memory usage.
[SVN r18681]
2003-06-05 15:14:52 +00:00
Bruno da Silva de Oliveira
6ca5280b2c - Fixed bug in GCCXMLParser
[SVN r18672]
2003-06-04 22:07:27 +00:00
Dave Abrahams
5da3e1deea Leak bug fixed thanks to gideon may <gideon-at-computer.org> for
reporting it.


[SVN r18671]
2003-06-04 20:47:39 +00:00
Dave Abrahams
1ae85d0e39 Added Jayacard
[SVN r18660]
2003-06-04 02:23:13 +00:00
Bruno da Silva de Oliveira
256e3a467c - Appliced a patch from Giulio Eulisse that allows unnamed enumerations to be
exported with an AllFromHeader construct


[SVN r18657]
2003-06-03 20:58:22 +00:00
Ralf W. Grosse-Kunstleve
4477fe4dd6 Python 2.3 Tru64 cxx compatibility & a little cleanup
[SVN r18652]
2003-06-03 02:58:43 +00:00
Bruno da Silva de Oliveira
5d1e245858 - New construct, add_method.
[SVN r18650]
2003-06-03 01:48:51 +00:00
Ralf W. Grosse-Kunstleve
ec750a44c9 missing include added (to avoid gcc 3.2 and tru64_cxx errors)
[SVN r18646]
2003-06-02 13:17:11 +00:00
Dave Abrahams
006f1d9802 Tests for to-python conversion of NULL shared_ptrs that didn't
originate as Python objects.


[SVN r18637]
2003-06-01 14:49:51 +00:00
Dave Abrahams
638b3d4ee1 added a small comment
[SVN r18636]
2003-06-01 14:48:53 +00:00
Dave Abrahams
a1cc1651fa clarified cygwin instructions
[SVN r18632]
2003-05-31 22:03:29 +00:00
Bruno da Silva de Oliveira
9fe141f5ad - Fixed bug related to --multiple and Vars
[SVN r18630]
2003-05-31 21:20:23 +00:00
Bruno da Silva de Oliveira
d52f0c7d40 - New tests
[SVN r18629]
2003-05-31 21:18:09 +00:00
Bruno da Silva de Oliveira
bb55c4a855 no message
[SVN r18628]
2003-05-31 20:57:03 +00:00
Dave Abrahams
f1a06b14de Handle null shared_ptrs
[SVN r18627]
2003-05-31 16:40:42 +00:00
Dave Abrahams
286f3dc093 Added #include <boost/python/detail/prefix.hpp> to ensure that all public Boost.Python headers begin by #including Python.h before as many system headers as possible.
[SVN r18626]
2003-05-31 14:53:02 +00:00
Dave Abrahams
a731322782 Test linking with the static library also.
[SVN r18624]
2003-05-31 13:44:16 +00:00
Dave Abrahams
0db07ec25e Added missing #include thanks to Ben Hutchings <ben.hutchings-at-businesswebsoftware.com>
[SVN r18623]
2003-05-31 13:43:29 +00:00
Bruno da Silva de Oliveira
bc112ba65f - Fixed bug in the generation of virtual methods.
[SVN r18619]
2003-05-30 21:52:33 +00:00
Dave Abrahams
62ba322658 updated ImageMagick info.
[SVN r18597]
2003-05-29 14:00:00 +00:00
Dave Abrahams
02135b550d OpenSceneGraph has a web page
[SVN r18596]
2003-05-29 13:14:48 +00:00
Ralf W. Grosse-Kunstleve
ee4b06bb50 static keyword removed (Aye, Aye Sir David Abrahams!)
[SVN r18570]
2003-05-27 21:07:40 +00:00
Ralf W. Grosse-Kunstleve
16c5435ca8 fix typo
[SVN r18554]
2003-05-26 22:03:46 +00:00
Bruno da Silva de Oliveira
2595049748 - Added the Techniques section
[SVN r18552]
2003-05-26 21:10:41 +00:00
Ralf W. Grosse-Kunstleve
5911691c0d workaround for silly MIPSpro compiler
[SVN r18550]
2003-05-26 19:46:05 +00:00
Ralf W. Grosse-Kunstleve
e369bddc84 avoid use of sizeof to enable compilation with buggy gcc 3.3; change as per David Abrahams' instructions
[SVN r18549]
2003-05-26 19:06:00 +00:00
Ralf W. Grosse-Kunstleve
dccf2bbb4a Tru64 cxx compatibility
[SVN r18548]
2003-05-26 19:03:24 +00:00
Bruno da Silva de Oliveira
eaab3fc038 - Fixed link to the tutorial
[SVN r18519]
2003-05-23 21:06:22 +00:00
Bruno da Silva de Oliveira
858e1aba67 - Support for global variables
- Bug fixes in ClassExporter


[SVN r18518]
2003-05-23 20:37:35 +00:00
Bruno da Silva de Oliveira
19eff7791d - HeaderExporter now doesn't export names that begin with "_"
- Bug in ClassExporter, was adding an attribute to the members of base classes in GenerateVirtualMethods


[SVN r18516]
2003-05-23 19:13:52 +00:00
Bruno da Silva de Oliveira
c81af4ffe0 - Two new questions, about compiling time and creating packages.
[SVN r18515]
2003-05-23 18:01:39 +00:00
Dave Abrahams
9675e4233b Fix a bug in dangling reference/pointer detection. Thanks to Daniel
Paull <dlp-at-fractaltechnologies.com> for reporting it.


[SVN r18498]
2003-05-22 15:13:22 +00:00
Dave Abrahams
e6a176bb1e Add initializer list for silly GCC
[SVN r18491]
2003-05-22 01:35:53 +00:00
Dave Abrahams
ff0980914b reinstate workarounds for vc7
[SVN r18490]
2003-05-22 01:34:04 +00:00
Dave Abrahams
43e5ccd0a7 object_core.hpp - allow wrapping of objects which take object managers in their constructors.
forward.hpp
pointer_holder.hpp
value_holder.hpp
test/long.[py/cpp]

pointee.hpp,    - begin making borland work.
cv_category.hpp,
referent_storage.hpp
instance.hpp

self.hpp        - removed flotsam

signature.hpp   - use vector instead of list

destroy.hpp     - removed needless complication

make_keyword_range_fn.hpp - support for simpler init using vectors

class_converters.hpp - workaround for pro7

inheritance.hpp - simplified; took out pro7 workarounds; factored out
                  inheritance_query.hpp to reduce recompilation
                  dependencies

make_ptr_instance.hpp - add missing typename

registry.cpp    - add a little invariant checking for metrowerks

class.cpp       - stopped relying on class_id typedef

test/data_members.cpp - added a few more tests to make sure things compile at least.
test/destroy_test.cpp - removed cheating has_trivial_destructor tests
test/enum.cpp         - added some pro7 workarounds
test/virtual_functions.[py/cpp] - added _some_ tests for callbacks which return by reference.


[SVN r18489]
2003-05-21 22:17:23 +00:00
Dave Abrahams
66d6272942 Use mpl::vector and simplify constructor generation so we don't have
to constantly reverse lists.


[SVN r18487]
2003-05-21 21:53:30 +00:00
Dave Abrahams
2f1b828967 Getter setter bugfixes for attribute access
[SVN r18486]
2003-05-21 21:52:26 +00:00
Dave Abrahams
622636dcf1 Killed unneeded #include
[SVN r18485]
2003-05-21 21:51:03 +00:00
Dave Abrahams
0c22c276bf Workaround CW bug
[SVN r18472]
2003-05-20 19:01:44 +00:00
Bruno da Silva de Oliveira
7a4a79c74e no message
[SVN r18461]
2003-05-20 03:17:19 +00:00
Bruno da Silva de Oliveira
06f454e1d3 - Some small memory improvements
[SVN r18459]
2003-05-20 01:35:13 +00:00
Bruno da Silva de Oliveira
c1dbd52de1 - Fixed bug where functions with the same name where not being exported correctly
[SVN r18458]
2003-05-19 23:58:35 +00:00
Dave Abrahams
c3f5679188 Bug fix
[SVN r18372]
2003-05-08 20:18:14 +00:00
Bruno da Silva de Oliveira
97e2628f95 - Fixed bug where GCCXML was generating more than one declaration of a given class
[SVN r18359]
2003-05-08 10:38:51 +00:00
Dave Abrahams
6cecfcb704 restore from disk crash
[SVN r18353]
2003-05-08 02:19:10 +00:00
Ralf W. Grosse-Kunstleve
022a5a16f5 Python 2.3b1 compatibility: LONG_LONG -> PY_LONG_LONG
[SVN r18337]
2003-05-01 05:19:47 +00:00
Bruno da Silva de Oliveira
a39a834e75 - Now trying to export forward declared classes gives a warning.
- Forward-declared classes are ignored with AllFromHeader
- Bug: now it's possible to exclude classes, functions and enums from AllFromHeader


[SVN r18289]
2003-04-23 00:42:34 +00:00
Dave Abrahams
2a1210384a Warning suppression from Dominique Devriese <dominique.devriese-at-student.kuleuven.ac.be>
[SVN r18288]
2003-04-22 14:21:37 +00:00
Bruno da Silva de Oliveira
d497611069 - New code (more generic) for declaring the smart pointer converters
[SVN r18269]
2003-04-16 22:35:09 +00:00
Dave Abrahams
46d8786f5a Tweak citations, etc.
[SVN r18265]
2003-04-16 16:12:34 +00:00
Dave Abrahams
b8028729eb NULL shared_ptr conversions, more tests for custom to-python shared_ptr registrations
[SVN r18263]
2003-04-16 14:32:14 +00:00
Dave Abrahams
30e7768a87 warning suppression
[SVN r18261]
2003-04-16 14:29:27 +00:00
Dave Abrahams
10dc663e07 *** empty log message ***
[SVN r18259]
2003-04-16 13:39:28 +00:00
Joel de Guzman
42fc57d761 tweaks
[SVN r18255]
2003-04-15 12:48:27 +00:00
Dave Abrahams
74cd2f4844 Fix bug report from Jacek Generowicz <jacek.generowicz-at-cern.ch>
[SVN r18254]
2003-04-15 11:10:53 +00:00
Bruno da Silva de Oliveira
a15135f1c1 - Fixed a inheritance bug, and added a test for it.
[SVN r18251]
2003-04-14 23:34:33 +00:00
Dave Abrahams
ccd84c0be6 Small changes to support new iterator adaptors in sandbox
[SVN r18212]
2003-04-09 11:57:59 +00:00
Joel de Guzman
510215f284 typo fixes
[SVN r18201]
2003-04-08 01:20:58 +00:00
Bruno da Silva de Oliveira
c7ea0aacd6 - Lots of fixes in the documentation
- Fixed support for return_opaque_pointer policy


[SVN r18199]
2003-04-08 01:01:32 +00:00
Bruno da Silva de Oliveira
f7f089d2d4 - Fixed bug where the order of instantiations in the --multiple mode could end up wrong
[SVN r18198]
2003-04-07 18:15:50 +00:00
Bruno da Silva de Oliveira
82721c77a1 - now includes documentation in the distribution
[SVN r18197]
2003-04-07 12:13:02 +00:00
Bruno da Silva de Oliveira
1c9bf7d91c - Generating code for the improved support of static data members of Boost.Python
[SVN r18193]
2003-04-06 20:47:10 +00:00
Bruno da Silva de Oliveira
9bf78396cb - fixed bug where return_opaque_pointer was not being added to the user context
[SVN r18192]
2003-04-06 13:43:19 +00:00
Bruno da Silva de Oliveira
d994e4719c - New unittests for linux, now testing single and multi modes
[SVN r18189]
2003-04-05 18:14:52 +00:00
Bruno da Silva de Oliveira
44b886bb76 - Added a new line after the end of the "_main.cpp" files in multiple mode
[SVN r18188]
2003-04-05 18:11:44 +00:00
Bruno da Silva de Oliveira
8d2f012bcf - added new option for generating bindings: --multiple
- some refactoring of the code
- now detects forward declarations and prints a warning about them


[SVN r18187]
2003-04-05 17:05:12 +00:00
Dave Abrahams
a86deed5f6 dummy
[SVN r18158]
2003-04-02 12:57:33 +00:00
Dave Abrahams
3fd9ad7a60 implement static data members
[SVN r18157]
2003-04-02 12:56:37 +00:00
Bruno da Silva de Oliveira
319a5cf97c - Added the experimental command line option -R, which is a workaround a gccxml's preprocessor bug
[SVN r18138]
2003-03-30 21:06:10 +00:00
Bruno da Silva de Oliveira
0fd503d6af - Bug where the full name of the operator wasn't used in the declaration
- Now converter operators that return char* or string are automatically named __str__ in Python
- Update documentation with info about Psyco


[SVN r18127]
2003-03-28 21:02:24 +00:00
Bruno da Silva de Oliveira
bf696026bd - Performance improvements (better psyco support, cache in CppParser)
[SVN r18123]
2003-03-28 12:47:15 +00:00
Bruno da Silva de Oliveira
734657244b - Changed the error message about missing policies.
[SVN r18118]
2003-03-27 23:40:59 +00:00
Bruno da Silva de Oliveira
d2470e4f9c - Fixed bug where virtual methods could end exported twice in the wrapper.
[SVN r18116]
2003-03-27 23:24:40 +00:00
Bruno da Silva de Oliveira
28a2792280 no message
[SVN r18107]
2003-03-27 17:23:52 +00:00
Bruno da Silva de Oliveira
cd985a33d8 - Added files to create a binary distribution
[SVN r18106]
2003-03-27 17:14:41 +00:00
Bruno da Silva de Oliveira
726d2beffd - Doc fix, about accessing the operators in the interface file
[SVN r18097]
2003-03-26 18:35:53 +00:00
Bruno da Silva de Oliveira
f04be3fc1b - No more "needs policy" warnings for functions that return PyObject*
[SVN r18096]
2003-03-26 15:25:38 +00:00
Bruno da Silva de Oliveira
b6927410d9 - Fixed stupid bug in HandlePolicy
[SVN r18095]
2003-03-26 15:06:14 +00:00
Bruno da Silva de Oliveira
44b2e1ef8b - Default policy for functions/methods that return const T& is now
return_value_policy<copy_const_reference>().


[SVN r18077]
2003-03-24 23:25:14 +00:00
Bruno da Silva de Oliveira
3d01e6af89 no message
[SVN r18067]
2003-03-23 18:29:11 +00:00
Bruno da Silva de Oliveira
00387b2076 - Documentation for smart-pointers
[SVN r18066]
2003-03-23 18:27:18 +00:00
Bruno da Silva de Oliveira
f9bf514801 - Added unittests for linux
[SVN r18065]
2003-03-23 18:23:09 +00:00
Bruno da Silva de Oliveira
fa27bddfab - added a case: wrapper for a virtual method
[SVN r18062]
2003-03-22 19:35:55 +00:00
Bruno da Silva de Oliveira
f27e8f8ddc no message
[SVN r18061]
2003-03-22 19:34:49 +00:00
Bruno da Silva de Oliveira
5b2623ff2e - bumped version number
[SVN r18060]
2003-03-22 19:33:33 +00:00
Bruno da Silva de Oliveira
a83a726b6e - Fixed bug where wrappers for virtual methods were ignored.
[SVN r18059]
2003-03-22 19:31:19 +00:00
Bruno da Silva de Oliveira
93df7e00a7 - Added new flags: -h, --help, -v, --version
[SVN r18058]
2003-03-22 18:20:16 +00:00
Bruno da Silva de Oliveira
6b7748a88d - Now exporting virtual methods from base classes too
[SVN r18057]
2003-03-22 18:19:25 +00:00
Bruno da Silva de Oliveira
f102c77fa2 no message
[SVN r18056]
2003-03-22 18:18:25 +00:00
Bruno da Silva de Oliveira
a4fa261b77 - New page about smart pointers, and misc fixes
[SVN r18055]
2003-03-22 18:16:01 +00:00
Dave Abrahams
8a15fefc6c update HippoDraw site
[SVN r18053]
2003-03-22 17:29:01 +00:00
Bruno da Silva de Oliveira
12a4cc16be - Added MANUAL support for shared_ptr and auto_ptrs. In the future, support should be automatic.
[SVN r18041]
2003-03-21 14:24:20 +00:00
Dave Abrahams
6335716342 fixed binary-ness
[SVN r18038]
2003-03-20 20:33:48 +00:00
Dave Abrahams
db0602ac2a *** empty log message ***
[SVN r18037]
2003-03-20 20:31:57 +00:00
Bruno da Silva de Oliveira
390ad530f1 - Bug: GenerateName in infos.py doesn't cover all possible cases.
[SVN r18028]
2003-03-20 04:55:38 +00:00
Dave Abrahams
6eb2e8d68a paper updates
[SVN r18027]
2003-03-20 02:56:22 +00:00
Dave Abrahams
b804b3b221 fix typo
[SVN r18025]
2003-03-20 02:53:47 +00:00
Joel de Guzman
936c1118bd Bump to v1.6.0
[SVN r18021]
2003-03-19 23:33:19 +00:00
Bruno da Silva de Oliveira
4ba7b8a8ff - Updated to reflect changes in declarations.py
[SVN r17997]
2003-03-19 05:55:28 +00:00
Bruno da Silva de Oliveira
70601e9da0 no message
[SVN r17995]
2003-03-19 05:54:26 +00:00
Bruno da Silva de Oliveira
c32d1f9614 - Fixed bug where the PointerDeclaration of functions and methods didn't have the & operator
[SVN r17994]
2003-03-19 05:03:49 +00:00
Dave Abrahams
e031f78ad4 news updates; added links to paper
[SVN r17993]
2003-03-19 03:57:59 +00:00
Bruno da Silva de Oliveira
7d0273051a - Fixed bug where an union that was a class member crashed pyste (unions are still not exported)
- Added support for int, double, float and long operators


[SVN r17989]
2003-03-19 02:49:18 +00:00
Bruno da Silva de Oliveira
29d537571b - Unit tests for the examples
[SVN r17987]
2003-03-19 02:47:29 +00:00
Dave Abrahams
39f243f76b Check in html and pdf versions
[SVN r17985]
2003-03-19 01:47:30 +00:00
Dave Abrahams
0712360cc9 Add funcptr FAQ
[SVN r17975]
2003-03-18 14:41:04 +00:00
Dave Abrahams
02c125cbb4 Add funcptr FAQ
[SVN r17974]
2003-03-18 14:40:09 +00:00
Bruno da Silva de Oliveira
13256fb7e9 - Fixed bugs in Linux
[SVN r17969]
2003-03-18 05:16:01 +00:00
Bruno da Silva de Oliveira
f11d757807 - Fixed bug where the permission bits were being copied to the tmp file
[SVN r17934]
2003-03-15 02:51:51 +00:00
Bruno da Silva de Oliveira
2e123849fb no message
[SVN r17931]
2003-03-14 23:39:04 +00:00
Bruno da Silva de Oliveira
2f6cfaf0e9 - Fixed definition of private default implementations
[SVN r17928]
2003-03-14 22:27:32 +00:00
Bruno da Silva de Oliveira
f9b216d6f9 - Now generating wrappers for protected and private virtual methods
[SVN r17924]
2003-03-14 21:12:55 +00:00
Dave Abrahams
5fdd10d77e respond to Ralf's suggestions
[SVN r17900]
2003-03-13 22:58:03 +00:00
Dave Abrahams
41de02d528 Added development history
[SVN r17899]
2003-03-13 22:05:50 +00:00
Ralf W. Grosse-Kunstleve
1c3d08f23a adjustment for MIPSpro
[SVN r17865]
2003-03-12 23:18:16 +00:00
Bruno da Silva de Oliveira
0f1dc1fd50 - fixed bug where non-public virtual methods where being exported
- fixed " call_method<%s>"  to " call_method< %s >"


[SVN r17860]
2003-03-12 21:26:45 +00:00
Dave Abrahams
cd06018820 opaque pointer conversions from Gottfried.Ganssauge@haufe.de
[SVN r17859]
2003-03-12 17:56:41 +00:00
Dave Abrahams
7816eb6344 fix copyrights
[SVN r17841]
2003-03-12 13:51:17 +00:00
Dave Abrahams
9813f4b55f Fix copyrights
[SVN r17840]
2003-03-12 13:50:18 +00:00
Dave Abrahams
f81ca21b22 opaque pointer conversions from Gottfried.Ganssauge@haufe.de
Acknowledgements for all


[SVN r17834]
2003-03-12 12:47:44 +00:00
Bruno da Silva de Oliveira
f1b7620c9e no message
[SVN r17828]
2003-03-12 03:42:37 +00:00
Bruno da Silva de Oliveira
7d5c453f59 no message
[SVN r17825]
2003-03-12 01:39:28 +00:00
Bruno da Silva de Oliveira
bc4feb42b5 - fixed "deepcopy" of infos bug
[SVN r17824]
2003-03-12 01:32:48 +00:00
Bruno da Silva de Oliveira
ca9920874f - fixed default arguments in virtual methods
[SVN r17823]
2003-03-12 01:32:00 +00:00
Bruno da Silva de Oliveira
415991f6fc - added a link to the Pyste documentation
[SVN r17806]
2003-03-11 03:34:28 +00:00
Bruno da Silva de Oliveira
20c52def19 - first version
[SVN r17805]
2003-03-11 03:29:22 +00:00
Bruno da Silva de Oliveira
7dcacbcfc4 - first version
[SVN r17804]
2003-03-11 03:20:24 +00:00
Ralf W. Grosse-Kunstleve
34bf1560a9 non-template function make_function1 must be inline
[SVN r17791]
2003-03-09 17:26:06 +00:00
Dave Abrahams
39195ac97a Fix for older EDGs
[SVN r17786]
2003-03-08 12:36:18 +00:00
Dave Abrahams
6aa71e1f72 Remove flotsam
[SVN r17783]
2003-03-08 08:53:19 +00:00
Dave Abrahams
257a6c45f8 Remove flotsam
[SVN r17782]
2003-03-08 08:51:45 +00:00
Dave Abrahams
d34a11b584 Fix for Python 2.3 long->int conversion behavior change
[SVN r17779]
2003-03-08 05:28:54 +00:00
Dave Abrahams
ca64c96133 Added dangling_reference FAQ
Various idiomatic MPL cleanups in indirect_traits.hpp
raw_function support
Patches for CWPro7.2
Patches to pass tests under Python 2.3 with the new bool type.
Tests for member operators returning const objects
Fixes for testing Boost.Python under Cygwin


[SVN r17777]
2003-03-08 03:53:19 +00:00
Ralf W. Grosse-Kunstleve
ff734e3269 MIPSpro compatibility
[SVN r17772]
2003-03-08 00:25:47 +00:00
Dave Abrahams
d028a60cc2 Workaround for vc7 bug (and regression test)
[SVN r17708]
2003-03-03 17:21:30 +00:00
Dave Abrahams
577f58149c tests for operators returning const objects
[SVN r17700]
2003-03-02 22:11:20 +00:00
Dave Abrahams
4b97e191b8 Fix formatting errors
[SVN r17697]
2003-03-02 15:25:35 +00:00
Ralf W. Grosse-Kunstleve
15a148ab10 minor polishing, corrections
[SVN r17696]
2003-03-02 02:50:49 +00:00
Dave Abrahams
5ac7741ca9 Updates for ACCU
[SVN r17695]
2003-03-02 00:55:07 +00:00
Dave Abrahams
4c7cff6e8e fix bad link
[SVN r17691]
2003-03-01 18:25:41 +00:00
Dave Abrahams
c6ca85b525 Added embedding tutorial from Dirk Gerrits. Thanks, Dirk!
[SVN r17690]
2003-03-01 18:19:38 +00:00
Dave Abrahams
99f45b474e Fix broken links
[SVN r17671]
2003-02-27 13:07:41 +00:00
Dave Abrahams
ee44c90e85 Fixes for Python and Cygwin testing
[SVN r17667]
2003-02-27 02:20:01 +00:00
Dave Abrahams
2c4fa48f46 Fixes for Intel5
[SVN r17658]
2003-02-26 13:48:16 +00:00
Aleksey Gurtovoy
90fcd9369d MPL names/directory structure refactoring
[SVN r17651]
2003-02-25 23:11:41 +00:00
Dave Abrahams
923feda9f7 update
[SVN r17627]
2003-02-25 03:54:38 +00:00
Dave Abrahams
6d7d2ea5fe initial checkin
[SVN r17626]
2003-02-25 03:31:36 +00:00
Dave Abrahams
4874a1801b Improved Boost.Python build reliability and documentation.
[SVN r17623]
2003-02-25 02:15:55 +00:00
Dave Abrahams
479d8fc0f6 shared_ptr deleter introspection support
miscellaneous cleanups and MPL idiom-izing


[SVN r17622]
2003-02-25 01:03:40 +00:00
Dave Abrahams
1c346b2531 fix metafunctions for MPL
[SVN r17621]
2003-02-25 00:57:33 +00:00
Dave Abrahams
5cdebaf896 gcc-2.95 workaround
[SVN r17620]
2003-02-25 00:56:55 +00:00
Joel de Guzman
600602f9dc Tutorial updates
[SVN r17598]
2003-02-23 03:53:36 +00:00
Joel de Guzman
2a530bb9d2 Tutorial updates. Added virtual functions with default implementations and reshufled the overloading topics to discuss manual overloading first.
[SVN r17597]
2003-02-23 02:23:15 +00:00
Dave Abrahams
acdad5caf3 better auto_ptr support
[SVN r17592]
2003-02-22 18:11:08 +00:00
Dave Abrahams
b42b243287 vc++7.1 bug workarounds
[SVN r17591]
2003-02-22 18:07:05 +00:00
Dave Abrahams
a76f5f3db7 mpl-ish cleanup
[SVN r17585]
2003-02-22 01:02:31 +00:00
Dave Abrahams
4e9f745d4a Fixups for cygwin
[SVN r17570]
2003-02-21 08:10:55 +00:00
Aleksey Gurtovoy
101961a7c6 remove old MSVC 6.5 workaround
[SVN r17564]
2003-02-20 21:31:46 +00:00
Aleksey Gurtovoy
29d1f860c1 ETI fixes
[SVN r17563]
2003-02-20 21:29:39 +00:00
Dave Abrahams
2663e73f1c Automatically add library-path values to RUN_PATH/RUN_LD_LIBRARY_PATH
[SVN r17562]
2003-02-20 20:28:05 +00:00
Aleksey Gurtovoy
1f9d0bb196 MSVC 7.0 ETI workaround
[SVN r17556]
2003-02-20 13:35:16 +00:00
Joel de Guzman
ff9f262fac tutorial update
[SVN r17512]
2003-02-18 18:44:16 +00:00
Dave Abrahams
472dc3bd41 made binary
[SVN r17320]
2003-02-11 17:30:23 +00:00
Dave Abrahams
6f91b93519 removed to make binary
[SVN r17319]
2003-02-11 17:29:27 +00:00
Joel de Guzman
47291f68b2 removed unnecessary file
[SVN r17318]
2003-02-11 12:18:47 +00:00
Ralf W. Grosse-Kunstleve
2b5ef3c572 Python 2.3 compatibility
[SVN r17271]
2003-02-07 18:56:16 +00:00
Ralf W. Grosse-Kunstleve
9c50496d93 second half of introduction rewritten; SWIG, SIP, CXX acknowledged as suggested by the PyConDC reviewers; technical points moved to Library Overview section
[SVN r17259]
2003-02-07 01:07:39 +00:00
Ralf W. Grosse-Kunstleve
80488e2f23 improved serialization and object interface sections; some sentences added to the end of the conclusion
[SVN r17258]
2003-02-06 22:42:36 +00:00
Dave Abrahams
ad8da7166b edits
[SVN r17257]
2003-02-06 20:56:26 +00:00
Dave Abrahams
55cb918c51 Add ownership question
[SVN r17250]
2003-02-06 13:50:53 +00:00
Dave Abrahams
ac55c5ccf7 Add FAQ reference
[SVN r17249]
2003-02-06 13:50:31 +00:00
Ralf W. Grosse-Kunstleve
5bcf90766f draft thinking hybrid section added
[SVN r17242]
2003-02-05 19:58:43 +00:00
Dave Abrahams
8f12fdea4a Remove workaround patches
[SVN r17128]
2003-01-31 18:37:11 +00:00
Dave Abrahams
6f687ee402 Added a FAQ
[SVN r17010]
2003-01-23 17:38:57 +00:00
Dave Abrahams
9dfe98abb0 bug fix + regression test
[SVN r17002]
2003-01-23 04:32:10 +00:00
Dave Abrahams
399cf70b92 Add staticmethod support from Nikolay Mladenov <nickm-at-sitius.com>
[SVN r16946]
2003-01-19 19:12:30 +00:00
Joel de Guzman
571790097a minor error fixed PodBayDoorException const& x
[SVN r16926]
2003-01-18 01:44:48 +00:00
Ralf W. Grosse-Kunstleve
21f3c7c8c2 Mac OS X status
[SVN r16904]
2003-01-15 06:19:23 +00:00
Vladimir Prus
9d26167ec1 Change use-requirements to usage-requirements in some library Jamfiles.
[SVN r16884]
2003-01-13 12:31:12 +00:00
Vladimir Prus
ba4906d05c Update V2 Jamfile for Boost.
[SVN r16882]
2003-01-13 10:05:01 +00:00
Dave Abrahams
e13a11eb7f Fix dict bug
[SVN r16866]
2003-01-11 00:18:59 +00:00
Ralf W. Grosse-Kunstleve
72b214b8db details from the introduction moved to design goals section
[SVN r16864]
2003-01-10 19:22:13 +00:00
Ralf W. Grosse-Kunstleve
84a8fb71b8 meager result after a real hard try
[SVN r16863]
2003-01-10 19:00:05 +00:00
Dave Abrahams
4f5272cab9 Folded in Ralf's first set of edits
[SVN r16856]
2003-01-10 15:17:46 +00:00
Dave Abrahams
5895047e23 Initial Checkin
[SVN r16855]
2003-01-10 15:11:05 +00:00
Dave Abrahams
50bcf8db34 Apply workarounds for msvc-stlport
[SVN r16854]
2003-01-10 15:04:05 +00:00
Dave Abrahams
7defd3bbed support for BOOST_PYTHON_STATIC_MODULE
clarification


[SVN r16788]
2003-01-07 18:03:17 +00:00
Dave Abrahams
b9ecc931b0 support for BOOST_PYTHON_STATIC_MODULE
[SVN r16787]
2003-01-07 17:44:06 +00:00
Dave Abrahams
b84a8fd737 support for BOOST_PYTHON_STATIC_MODULE
[SVN r16786]
2003-01-07 17:38:08 +00:00
Dave Abrahams
2b1a2ce09c Build static versions of the library too.
[SVN r16785]
2003-01-07 17:30:51 +00:00
Dave Abrahams
bcf36610e1 Check in VisualStudio support from Brett Calcott
[SVN r16717]
2002-12-29 17:27:52 +00:00
Dave Abrahams
1bb3254d4d Check in changes from Brett Calcott
[SVN r16716]
2002-12-29 16:53:48 +00:00
Beman Dawes
0f95d507c4 add or update See www.boost.org comments
[SVN r16708]
2002-12-27 16:51:53 +00:00
Dave Abrahams
aa58e21bda Bug fix, thanks to "Daniel Paull" <dlp@fractaltechnologies.com> for
reporting it.


[SVN r16698]
2002-12-24 04:49:33 +00:00
Dave Abrahams
eac0412d18 Fixed comment
[SVN r16676]
2002-12-21 22:12:31 +00:00
Dave Abrahams
0c8aa84f2f Enable automatic downcasting to registered classes for pointers, references, and smart pointers
[SVN r16673]
2002-12-20 18:19:18 +00:00
Dave Abrahams
3d874d1618 Major simplification of from_python conversion avoids registering
converters for every class.


[SVN r16669]
2002-12-20 00:04:40 +00:00
Dave Abrahams
b8edd99dbd Fix typo thanks to "William Trenker" <wtrenker@hotmail.com>
[SVN r16657]
2002-12-18 21:12:02 +00:00
Dave Abrahams
0df5ebf0fa Fix to allow accessing enums as data members
[SVN r16656]
2002-12-18 21:11:16 +00:00
Dave Abrahams
809535b934 clarifications
[SVN r16655]
2002-12-18 21:09:15 +00:00
Dave Abrahams
854e957b78 Workaround for MacOS GCC problem:
#define B0 0


[SVN r16654]
2002-12-18 19:09:34 +00:00
Dave Abrahams
df24f29232 nonconformance workaround from Gottfried.Ganssauge@HAUFE.DE
[SVN r16653]
2002-12-18 17:56:42 +00:00
Joel de Guzman
14c7d9ab14 typo error __rsub__ to __sub__
[SVN r16641]
2002-12-18 01:23:21 +00:00
Dave Abrahams
0e36ac6b72 Bug fix with construction of std::exception
[SVN r16625]
2002-12-16 21:14:30 +00:00
Dave Abrahams
0d2cdbbdfe GCC-2.95.2 workarounds
[SVN r16620]
2002-12-16 04:01:50 +00:00
Dave Abrahams
48f9bee21e Fix typo due to "William Trenker" <wtrenker@hotmail.com>
[SVN r16619]
2002-12-16 03:30:34 +00:00
Dave Abrahams
dd8fc049ff update news
[SVN r16607]
2002-12-14 00:17:22 +00:00
Dave Abrahams
abd22f1273 Handle unsigned long values that don't fit in a long.
[SVN r16606]
2002-12-14 00:10:52 +00:00
Dave Abrahams
4a5817d8ba enum export
[SVN r16604]
2002-12-13 20:04:34 +00:00
Dave Abrahams
eab084c9a2 enum export
[SVN r16603]
2002-12-13 19:58:24 +00:00
Dave Abrahams
80ea2383a7 Fix references to test library
[SVN r16585]
2002-12-10 23:05:38 +00:00
Dave Abrahams
ec76fbe027 Apply fixes from Dirk Gerrits <dirk@gerrits.homeip.net>
[SVN r16517]
2002-12-04 17:10:55 +00:00
Dave Abrahams
c772038e77 Apply fixes from Dirk Gerrits <dirk@gerrits.homeip.net>
[SVN r16506]
2002-12-04 13:36:03 +00:00
Dave Abrahams
59b1a8e71c Apply fixes from Dirk Gerrits <dirk@gerrits.homeip.net>
[SVN r16491]
2002-12-03 18:08:12 +00:00
Dave Abrahams
83c38876fe Simplify, simplify!!
[SVN r16483]
2002-12-02 22:57:47 +00:00
Dave Abrahams
9163c40a1a Further suppressed internal structure overflow problems which were cropping up with msvc6/7.
[SVN r16482]
2002-12-02 19:41:45 +00:00
Dave Abrahams
8b79380977 Less-taxing version of MPL lambda support for msvc6/7
[SVN r16480]
2002-12-02 16:18:35 +00:00
Dave Abrahams
34c9d895c8 Relaxed rules for using scope()
[SVN r16476]
2002-12-02 14:29:11 +00:00
Dave Abrahams
bf8bb83ec5 initial commit
[SVN r16473]
2002-12-02 12:40:18 +00:00
Dave Abrahams
328697952f automatic shared_ptr from_python conversions
[SVN r16467]
2002-12-02 01:37:39 +00:00
Dave Abrahams
3c19b89d9a Added reset()
[SVN r16466]
2002-12-01 16:14:44 +00:00
Dave Abrahams
ae9f394906 Added reset()
[SVN r16465]
2002-12-01 16:07:54 +00:00
Dave Abrahams
8467f36b80 Kill errant `typename'
[SVN r16464]
2002-12-01 04:40:05 +00:00
Dave Abrahams
43a9571b2c Fixed some technical problems with smart pointer support uncovered by
STLPort's debug mode. Unfortunately, had to expand Dereferenceable
requirements.


[SVN r16459]
2002-11-29 22:43:27 +00:00
Dave Abrahams
bbef71dc7d Progress on embedding example for unix.
[SVN r16458]
2002-11-29 20:23:54 +00:00
Dave Abrahams
c4df3c6562 Bug fix
[SVN r16442]
2002-11-27 14:23:07 +00:00
Dave Abrahams
0ad3bfd0ab Finally fixed polymorphism issues
[SVN r16435]
2002-11-27 07:04:32 +00:00
Dave Abrahams
fb7c450b76 Added is_reference_to_member_function_pointer
[SVN r16434]
2002-11-27 06:19:45 +00:00
Dave Abrahams
3fc70519cf Use boost is_polymorphic trait
[SVN r16433]
2002-11-27 06:19:13 +00:00
Dave Abrahams
98c2bf8ff2 Restored some missing v1 acknowledgements
[SVN r16432]
2002-11-27 02:18:52 +00:00
Dave Abrahams
f9c8bf15bb Restore CWPro7.2 to health. Also improve source organization slightly
[SVN r16416]
2002-11-26 02:47:17 +00:00
Dave Abrahams
a7e19ffb0b Refactored def() logic; moved assert_default_constructible into the
holder selectorbecause it was getting the wrong answer in some cases.


[SVN r16415]
2002-11-26 01:06:41 +00:00
Dave Abrahams
7609a1c7c6 Refactored; added static assertions against the specification of a default implementation
[SVN r16414]
2002-11-25 22:03:42 +00:00
Dave Abrahams
087e2d6e35 Add additional argument for default implementation of virtual functions
Fully commented


[SVN r16413]
2002-11-25 21:57:23 +00:00
Dave Abrahams
bb7710a5a2 Suppress GCC warning
[SVN r16412]
2002-11-25 21:19:35 +00:00
Dave Abrahams
0d582e0e79 Suppress GCC warning
[SVN r16411]
2002-11-25 20:54:37 +00:00
Dave Abrahams
3d0579cc08 Fix for VC7. For some reason lexical_cast doesn't seem to work out too
well. We'll need to be careful how we do type_info decoding once we
get the G++ fixes in.


[SVN r16410]
2002-11-25 20:52:49 +00:00
Dave Abrahams
352e390c7b Added tests for embedding demonstration
[SVN r16409]
2002-11-25 18:32:14 +00:00
Dave Abrahams
394037a127 updated
[SVN r16408]
2002-11-25 16:12:27 +00:00
Dave Abrahams
9d4e235cf6 add imul notes
[SVN r16397]
2002-11-25 03:41:34 +00:00
Dave Abrahams
cfbc1a6b48 Fully removed convertible() test from to_python converter protocol
Added tests for detecting unregistered classes when converting
indirectly to python.


[SVN r16396]
2002-11-25 01:57:57 +00:00
Dave Abrahams
31b8b58de9 CW workaround
[SVN r16393]
2002-11-24 21:45:09 +00:00
Dave Abrahams
a77a835694 New function invocation mechanism. This is the major groundwork for handling virtual functions with default implementations properly
[SVN r16390]
2002-11-24 03:26:28 +00:00
Dave Abrahams
dca5c5108b update
[SVN r16389]
2002-11-24 03:25:13 +00:00
Dave Abrahams
e14e4e156c New function invocation mechanism. This is the major groundwork for handling virtual functions with default implementations properly
[SVN r16388]
2002-11-24 02:43:24 +00:00
Dave Abrahams
05ce65d9d2 cleanup
[SVN r16387]
2002-11-23 22:31:13 +00:00
Dave Abrahams
b952e45036 Clip unneeded bind.hpp #include
[SVN r16386]
2002-11-23 22:30:48 +00:00
Dave Abrahams
4c630512fe Add missing add_const #include
[SVN r16385]
2002-11-23 22:18:23 +00:00
Dave Abrahams
0461d25de6 Add some qualification
[SVN r16384]
2002-11-23 22:16:55 +00:00
Dave Abrahams
2df120af72 Suppress a VC6 ICE
[SVN r16383]
2002-11-23 22:16:00 +00:00
Dave Abrahams
791b7e1a1b Tidy
[SVN r16381]
2002-11-23 20:03:49 +00:00
Dave Abrahams
f6f4e59473 Add notes about targeting Cygwin GCC
[SVN r16380]
2002-11-23 20:03:24 +00:00
Dave Abrahams
60924e82e2 On our way to polymorphism
[SVN r16374]
2002-11-23 02:59:45 +00:00
Dave Abrahams
75bd427b8e Bugfix
[SVN r16354]
2002-11-21 00:21:23 +00:00
Dave Abrahams
715118ce39 Bugfix
[SVN r16353]
2002-11-21 00:19:27 +00:00
Dave Abrahams
e3deb8275d update
[SVN r16351]
2002-11-20 23:07:32 +00:00
Dave Abrahams
c30e12f956 Make scope constructor explicit
[SVN r16350]
2002-11-20 22:58:57 +00:00
Ralf W. Grosse-Kunstleve
983b23db92 some missing html markup added
[SVN r16349]
2002-11-20 18:09:17 +00:00
Ralf W. Grosse-Kunstleve
ed2da9bedb list cctbx
[SVN r16348]
2002-11-20 18:01:44 +00:00
Dave Abrahams
409ff3c179 Added missing test
[SVN r16337]
2002-11-20 03:04:51 +00:00
Dave Abrahams
39eab72293 bugfixes
add_property now uses member_function_cast


[SVN r16335]
2002-11-20 01:14:16 +00:00
Dave Abrahams
71ea2bec86 more notes
[SVN r16330]
2002-11-19 17:39:40 +00:00
Dave Abrahams
c9af6ca94b Add missing copyright notices
[SVN r16329]
2002-11-19 17:39:17 +00:00
Dave Abrahams
72d5bac69f Add PSF copyright and change summary
[SVN r16327]
2002-11-19 16:56:55 +00:00
Dave Abrahams
6e0733afa2 Remove Tom's email address
[SVN r16315]
2002-11-19 01:33:07 +00:00
Dave Abrahams
e660cc50c6 Added Support link
[SVN r16299]
2002-11-17 05:59:12 +00:00
Dave Abrahams
e6b40f54cd initial commit
[SVN r16298]
2002-11-17 05:58:45 +00:00
Dave Abrahams
c2af21169d More notes
[SVN r16297]
2002-11-16 23:48:09 +00:00
Dave Abrahams
4f7af97f8c Bug fix thanks to Mark Russell <mrussell8081@pacbell.net>
[SVN r16296]
2002-11-16 23:23:45 +00:00
Dave Abrahams
57f54952c3 Bug fix thanks to Mark Russell <mrussell8081@pacbell.net>
[SVN r16295]
2002-11-16 23:22:30 +00:00
Dave Abrahams
b321b6d9db Tweaks, pseudocode
[SVN r16294]
2002-11-16 22:45:46 +00:00
Dave Abrahams
56c5227cf7 added note
[SVN r16293]
2002-11-16 22:28:28 +00:00
Dave Abrahams
ae2931ba1b initial commit
[SVN r16292]
2002-11-16 22:12:46 +00:00
Dave Abrahams
9e3589ec4d Added projects page link
[SVN r16290]
2002-11-16 20:50:21 +00:00
Dave Abrahams
61b7094dbd Added EMSolve entry
[SVN r16289]
2002-11-16 20:48:43 +00:00
Dave Abrahams
50ecc751d1 Added Fortress entry
[SVN r16288]
2002-11-16 20:39:56 +00:00
Dave Abrahams
bb536a0eaa One more step towards handling polymorphism: now we can sort out a 4th parameter
[SVN r16287]
2002-11-16 20:03:59 +00:00
Dave Abrahams
8b7527318d vc6/7 workaround
[SVN r16286]
2002-11-16 20:01:44 +00:00
Dave Abrahams
f2ac0145da is_reference_to_function_pointer implementation
[SVN r16278]
2002-11-16 06:55:04 +00:00
Dave Abrahams
06fe0f1bcc is_reference_to_function implementation
[SVN r16276]
2002-11-16 06:00:52 +00:00
Dave Abrahams
7ea2447246 Bug fix
[SVN r16273]
2002-11-16 03:38:24 +00:00
Dave Abrahams
0adf4477a3 vc7.1 workaround
[SVN r16267]
2002-11-16 00:45:26 +00:00
Dave Abrahams
b3311fd59d *** empty log message ***
[SVN r16266]
2002-11-15 22:19:40 +00:00
Dave Abrahams
ae109f13a2 *** empty log message ***
[SVN r16260]
2002-11-15 17:29:15 +00:00
Dave Abrahams
cb1901e111 initial commit
[SVN r16259]
2002-11-15 17:02:31 +00:00
Dave Abrahams
bbc052bedc Fix example
[SVN r16256]
2002-11-15 12:25:29 +00:00
Dave Abrahams
f2797ec262 Auto-detection of class memebers wrapped with make_getter()
[SVN r16241]
2002-11-14 17:41:13 +00:00
Dave Abrahams
a21727741f c1204 workaround documented
[SVN r16235]
2002-11-14 12:16:40 +00:00
Dave Abrahams
5f022269b1 Added News page, links back to top of docs
[SVN r16229]
2002-11-14 02:09:43 +00:00
Dave Abrahams
0e76fcf706 auto_ptr support
[SVN r16228]
2002-11-14 01:40:16 +00:00
Dave Abrahams
6b4dc2901d Fix broken link
[SVN r16227]
2002-11-13 22:56:41 +00:00
Dave Abrahams
bcf864fce3 Attempt to handle derived target types
[SVN r16224]
2002-11-13 17:22:48 +00:00
Dave Abrahams
0168d8fbc8 Be more explicit about the Cygwin stuff
[SVN r16215]
2002-11-12 19:36:19 +00:00
Dave Abrahams
88b1c1b926 Allow member pointers from base classes in def_readonly and
def_readwrite.


[SVN r16214]
2002-11-12 17:48:56 +00:00
Dave Abrahams
1f93827b63 Squash bogus warnings
[SVN r16196]
2002-11-11 13:49:09 +00:00
Dave Abrahams
8e3ba0bba3 Improve error messages
[SVN r16147]
2002-11-07 14:41:40 +00:00
Dave Abrahams
42a0441cb8 Doc fix from "Brett Calcott" <brett.calcott@paradise.net.nz>
[SVN r16145]
2002-11-07 13:12:05 +00:00
Joel de Guzman
7b091b86d2 tutorial tweaks
[SVN r16004]
2002-10-28 08:30:31 +00:00
Dave Abrahams
f346eaf693 grammar fix
[SVN r16001]
2002-10-28 07:33:01 +00:00
Dave Abrahams
038be89766 Build with Cygwin
[SVN r16000]
2002-10-28 04:22:14 +00:00
Dave Abrahams
a682dd9362 Fix a doc bug
[SVN r15981]
2002-10-25 04:47:39 +00:00
Joel de Guzman
387e8aadc6 changes to no_init and deriving classes
[SVN r15979]
2002-10-24 21:33:40 +00:00
Joel de Guzman
da273519fd added non_copyable to second version of class_<Base, BaseWrap...
[SVN r15978]
2002-10-24 21:12:37 +00:00
Joel de Guzman
8c2d6bb31b correction Var-->Num
[SVN r15977]
2002-10-24 20:50:04 +00:00
Vladimir Prus
3cb4a029e0 Improve Boost.Python building.
* libs/python/build/Jamfile.v2: Sense the location of python headers. Export
  include paths.

* libs/python/example/Jamfile.v2: New file.

* new/targets.jam: Use refined properties for constructed
    dependency properties

* new/gcc.jam: Handle 'find-library'. Set soname for dynamic libraries.

* new/builtin.jam: New feature 'find-library'.


[SVN r15966]
2002-10-23 12:12:00 +00:00
Dave Abrahams
037f952136 Added funding credit
[SVN r15948]
2002-10-16 22:47:44 +00:00
Dave Abrahams
7fc441801d Allow embedded nulls in std::string <-> Python string conversions,
patch from greg Landrum <greglandrum@mindspring.com>.

Tests by Dave A.


[SVN r15945]
2002-10-16 20:24:38 +00:00
Dave Abrahams
c389e057b4 Added return_by_value, enhanced data member support to handle constant members
[SVN r15935]
2002-10-15 15:46:34 +00:00
Dave Abrahams
2c7829f50e initial checkin
[SVN r15930]
2002-10-15 11:59:39 +00:00
Dave Abrahams
0593074196 Patches to support Synopsis
[SVN r15906]
2002-10-12 15:37:34 +00:00
Dave Abrahams
c7626150fc Move final RC_1_29_0 changes back to trunk
[SVN r15877]
2002-10-10 18:11:14 +00:00
Dave Abrahams
f6990fedc7 Move final RC_1_29_0 changes back to trunk
[SVN r15875]
2002-10-10 18:09:46 +00:00
Dave Abrahams
adb02376eb Move final RC_1_29_0 changes back to trunk
[SVN r15872]
2002-10-10 18:05:51 +00:00
Dave Abrahams
65b6eb0c27 Move final RC_1_29_0 changes back to trunk
[SVN r15871]
2002-10-10 18:01:58 +00:00
Dave Abrahams
654354e681 GCC 2.96 bug workaround
[SVN r15864]
2002-10-10 15:59:12 +00:00
571 changed files with 33444 additions and 5064 deletions

View File

@@ -10,8 +10,7 @@
subproject libs/python/build ;
# bring in the rules for python
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
include <module@>python.jam ;
import python ;
if [ check-python-config ]
{
@@ -23,44 +22,73 @@ if [ check-python-config ]
bpl-linkflags = <linkflags>"-e initlibboost_python" ;
}
# Enabling intrinsics (/0i) or maximize speed (/02) seem to cause
# internal compiler errors with this toolset.
local msvc-stlport-workarounds
= <optimization>off "<cxxflags>-Ogty -O1 -Gs" ;
local sources =
numeric.cpp
list.cpp
long.cpp
dict.cpp
tuple.cpp
str.cpp
slice.cpp
aix_init_module.cpp
converter/from_python.cpp
converter/registry.cpp
converter/type_id.cpp
object/enum.cpp
object/class.cpp
object/function.cpp
object/inheritance.cpp
object/life_support.cpp
object/pickle_support.cpp
errors.cpp
module.cpp
converter/builtin_converters.cpp
converter/arg_to_python_base.cpp
object/iterator.cpp
object_protocol.cpp
object_operators.cpp
;
dll boost_python
:
../src/numeric.cpp
../src/list.cpp
../src/long.cpp
../src/dict.cpp
../src/tuple.cpp
../src/str.cpp
../src/aix_init_module.cpp
../src/converter/from_python.cpp
../src/converter/registry.cpp
../src/converter/type_id.cpp
../src/object/enum.cpp
../src/object/class.cpp
../src/object/function.cpp
../src/object/inheritance.cpp
../src/object/life_support.cpp
../src/object/pickle_support.cpp
../src/errors.cpp
../src/module.cpp
../src/converter/builtin_converters.cpp
../src/converter/arg_to_python_base.cpp
../src/object/iterator.cpp
../src/object_protocol.cpp
../src/object_operators.cpp
:
$(BOOST_PYTHON_V2_PROPERTIES)
: ../src/$(sources)
: $(BOOST_PYTHON_V2_PROPERTIES)
<define>BOOST_PYTHON_SOURCE
$(bpl-linkflags)
<msvc-stlport><release>$(msvc-stlport-workarounds)
<darwin><*><linkflags>-bind_at_load
;
stage bin-stage : <dll>boost_python
:
<tag><debug>"_debug"
<tag><debug-python>"_pydebug"
template extension
: <dll>boost_python
: <sysinclude>../../..
;
lib boost_python
: # sources
../src/$(sources)
: # requirements
$(BOOST_PYTHON_V2_PROPERTIES)
<define>BOOST_PYTHON_SOURCE
<define>BOOST_STATIC_LIB
$(bpl-linkflags)
<msvc-stlport><release>$(msvc-stlport-workarounds)
;
stage bin-stage : <dll>boost_python <lib>boost_python
: <tag><debug>"_debug"
<tag><debug-python>"_pydebug"
:
debug release
;
}
install python lib
: <dll>boost_python <lib>boost_python
;
}

88
build/Jamfile.v2 Normal file
View File

@@ -0,0 +1,88 @@
import os ;
import modules ;
# Use a very crude way to sense there python is locatted
local PYTHON_PATH = [ modules.peek : PYTHON_PATH ] ;
ECHO "XXX" $(PYTHON_PATH) ;
if [ GLOB /usr/local/include/python2.2 : * ]
{
PYTHON_PATH = /usr/local ;
}
else if [ GLOB /usr/include/python2.2 : * ]
{
PYTHON_PATH = /usr ;
}
if [ os.name ] in CYGWIN NT
{
lib_condition = <link>shared: ;
defines = USE_DL_IMPORT ;
# Declare a target for the python interpreter library
lib python : : <name>python22 <search>$(PYTHON_PATH)/libs ;
PYTHON_LIB = python ;
}
else
{
lib python : : <name>python2.2 ;
PYTHON_LIB = python ;
}
if $(PYTHON_PATH) {
project boost/python
: source-location ../src
: requirements <include>$(PYTHON_PATH)/include
$(lib_condition)<library-path>$(PYTHON_PATH)/libs
<link>shared:<library>$(PYTHON_LIB)
<define>$(defines)
: usage-requirements # requirement that will be propageted to *users* of this library
<include>$(PYTHON_PATH)/include
# We have a bug which causes us to conclude that conditionalized
# properties in this section are not free.
# $(lib_condition)<library-path>$(PYTHON_PATH)/lib/python2.2/config
# <shared>true:<find-library>$(PYTHON_LIB)
<library-path>$(PYTHON_PATH)/lib/python2.2/config
<library>$(PYTHON_LIB)
;
lib boost_python
:
numeric.cpp
list.cpp
long.cpp
dict.cpp
tuple.cpp
str.cpp
aix_init_module.cpp
converter/from_python.cpp
converter/registry.cpp
converter/type_id.cpp
object/enum.cpp
object/class.cpp
object/function.cpp
object/inheritance.cpp
object/life_support.cpp
object/pickle_support.cpp
errors.cpp
module.cpp
converter/builtin_converters.cpp
converter/arg_to_python_base.cpp
object/iterator.cpp
object_protocol.cpp
object_operators.cpp
: <link>static:<define>BOOST_PYTHON_STATIC_LIB
<define>BOOST_PYTHON_SOURCE
: <link>shared
;
}

View File

@@ -0,0 +1,882 @@
# Microsoft Developer Studio Project File - Name="boost_python" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=BOOST_PYTHON - WIN32 RELEASE
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "boost_python.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "boost_python.mak" CFG="BOOST_PYTHON - WIN32 RELEASE"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "boost_python - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "boost_python - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "boost_python - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../bin-stage"
# PROP Intermediate_Dir "release-obj"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
F90=df.exe
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BPL_EXPORTS" /YX /FD /Zm800 /Zm800 /Zm800 /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../../" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOOST_PYTHON_DYNAMIC_LIB" /D "BOOST_PYTHON_SOURCE" /FD /Zm800 /Zm800 /Zm800 /Zm800 /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x1409 /d "NDEBUG"
# ADD RSC /l 0x1409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib /nologo /dll /machine:I386
!ELSEIF "$(CFG)" == "boost_python - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "../bin-stage"
# PROP Intermediate_Dir "debug-obj"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
F90=df.exe
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BPL_EXPORTS" /YX /FD /Zm800 /Zm800 /Zm800 /GZ /c
# ADD CPP /nologo /MDd /W3 /GR /GX /Zi /Od /I "../../../../" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOOST_PYTHON_DYNAMIC_LIB" /D "BOOST_PYTHON_SOURCE" /FD /Zm800 /Zm800 /Zm800 /Zm800 /Zm800 /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x1409 /d "_DEBUG"
# ADD RSC /l 0x1409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"../bin-stage/boost_python_debug.dll" /pdbtype:sept
!ENDIF
# Begin Target
# Name "boost_python - Win32 Release"
# Name "boost_python - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\src\aix_init_module.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\converter\arg_to_python_base.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\converter\builtin_converters.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\object\class.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\dict.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\object\enum.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\errors.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\converter\from_python.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\object\function.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\object\inheritance.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\object\iterator.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\object\life_support.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\list.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\long.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\module.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\numeric.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\object_operators.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\object_protocol.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\object\pickle_support.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\converter\registry.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\str.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\tuple.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\converter\type_id.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Group "detail"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\aix_init_module.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\api_placeholder.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\arg_tuple_size.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\borrowed_ptr.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\call_object.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\caller.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\char_array.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\config.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\construct.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\convertible.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\cv_category.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\decorated_type_id.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\def_helper.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\defaults_def.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\defaults_gen.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\dependent.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\destroy.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\exception_handler.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\force_instantiate.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\if_else.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\indirect_traits.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\make_keyword_range_fn.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\make_tuple.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\map_entry.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\member_function_cast.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\module_base.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\module_init.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\msvc_typeinfo.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\none.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\not_specified.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\operator_id.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\overloads_fwd.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\pointee.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\preprocessor.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\python22_fixed.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\raw_pyobject.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\referent_storage.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\result.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\returning.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\scope.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\string_literal.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\target.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\translate_exception.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\type_list.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\type_list_impl.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\type_list_impl_no_pts.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\type_list_utils.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\unwind_type.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\void_ptr.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\void_return.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\detail\wrap_python.hpp
# End Source File
# End Group
# Begin Group "converter"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\arg_from_python.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\arg_to_python.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\arg_to_python_base.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\builtin_converters.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\constructor_function.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\convertible_function.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\from_python.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\implicit.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\obj_mgr_arg_from_python.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\object_manager.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\pointer_type_id.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\pyobject_traits.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\pyobject_type.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\pytype_arg_from_python.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\pytype_object_mgr_traits.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\registered.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\registered_pointee.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\registrations.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\registry.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\return_from_python.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\rvalue_from_python_data.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\converter\to_python_function_type.hpp
# End Source File
# End Group
# Begin Group "object"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\add_to_namespace.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\class.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\class_converters.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\class_detail.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\class_wrapper.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\construct.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\enum_base.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\find_instance.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\forward.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\function.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\function_handle.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\function_object.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\inheritance.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\instance.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\iterator.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\iterator_core.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\life_support.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\make_holder.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\make_instance.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\pickle_support.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\pointer_holder.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\py_function.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\select_holder.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\value_holder.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object\value_holder_fwd.hpp
# End Source File
# End Group
# Begin Source File
SOURCE=..\..\..\..\boost\python\arg_from_python.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\args.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\args_fwd.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\back_reference.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\base_type_traits.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\bases.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\borrowed.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\call.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\call_method.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\cast.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\class.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\class_fwd.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\copy_const_reference.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\copy_non_const_reference.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\data_members.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\def.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\default_call_policies.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\dict.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\enum.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\errors.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\exception_translator.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\extract.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\handle.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\handle_fwd.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\has_back_reference.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\implicit.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\init.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\instance_holder.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\iterator.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\list.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\long.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\lvalue_from_pytype.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\make_function.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\manage_new_object.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\module.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\module_init.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\numeric.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object_attributes.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object_call.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object_core.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object_fwd.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object_items.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object_operators.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object_protocol.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object_protocol_core.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\object_slices.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\operators.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\operators2.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\other.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\overloads.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\pointee.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\proxy.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\ptr.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\refcount.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\reference_existing_object.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\return_internal_reference.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\return_value_policy.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\scope.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\self.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\signature.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\slice_nil.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\str.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\tag.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\to_python_converter.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\to_python_indirect.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\to_python_value.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\tuple.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\type_id.hpp
# End Source File
# Begin Source File
SOURCE=..\..\..\..\boost\python\with_custodian_and_ward.hpp
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "boost_python"=".\boost_python.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

1127
doc/PyConDC_2003/bpl.html Executable file

File diff suppressed because it is too large Load Diff

BIN
doc/PyConDC_2003/bpl.pdf Executable file

Binary file not shown.

947
doc/PyConDC_2003/bpl.txt Normal file
View File

@@ -0,0 +1,947 @@
+++++++++++++++++++++++++++++++++++++++++++
Building Hybrid Systems with Boost.Python
+++++++++++++++++++++++++++++++++++++++++++
:Author: David Abrahams
:Contact: dave@boost-consulting.com
:organization: `Boost Consulting`_
:date: $Date$
:Author: Ralf W. Grosse-Kunstleve
:copyright: Copyright David Abrahams and Ralf W. Grosse-Kunstleve 2003. All rights reserved
.. contents:: Table of Contents
.. _`Boost Consulting`: http://www.boost-consulting.com
==========
Abstract
==========
Boost.Python is an open source C++ library which provides a concise
IDL-like interface for binding C++ classes and functions to
Python. Leveraging the full power of C++ compile-time introspection
and of recently developed metaprogramming techniques, this is achieved
entirely in pure C++, without introducing a new syntax.
Boost.Python's rich set of features and high-level interface make it
possible to engineer packages from the ground up as hybrid systems,
giving programmers easy and coherent access to both the efficient
compile-time polymorphism of C++ and the extremely convenient run-time
polymorphism of Python.
==============
Introduction
==============
Python and C++ are in many ways as different as two languages could
be: while C++ is usually compiled to machine-code, Python is
interpreted. Python's dynamic type system is often cited as the
foundation of its flexibility, while in C++ static typing is the
cornerstone of its efficiency. C++ has an intricate and difficult
compile-time meta-language, while in Python, practically everything
happens at runtime.
Yet for many programmers, these very differences mean that Python and
C++ complement one another perfectly. Performance bottlenecks in
Python programs can be rewritten in C++ for maximal speed, and
authors of powerful C++ libraries choose Python as a middleware
language for its flexible system integration capabilities.
Furthermore, the surface differences mask some strong similarities:
* 'C'-family control structures (if, while, for...)
* Support for object-orientation, functional programming, and generic
programming (these are both *multi-paradigm* programming languages.)
* Comprehensive operator overloading facilities, recognizing the
importance of syntactic variability for readability and
expressivity.
* High-level concepts such as collections and iterators.
* High-level encapsulation facilities (C++: namespaces, Python: modules)
to support the design of re-usable libraries.
* Exception-handling for effective management of error conditions.
* C++ idioms in common use, such as handle/body classes and
reference-counted smart pointers mirror Python reference semantics.
Given Python's rich 'C' interoperability API, it should in principle
be possible to expose C++ type and function interfaces to Python with
an analogous interface to their C++ counterparts. However, the
facilities provided by Python alone for integration with C++ are
relatively meager. Compared to C++ and Python, 'C' has only very
rudimentary abstraction facilities, and support for exception-handling
is completely missing. 'C' extension module writers are required to
manually manage Python reference counts, which is both annoyingly
tedious and extremely error-prone. Traditional extension modules also
tend to contain a great deal of boilerplate code repetition which
makes them difficult to maintain, especially when wrapping an evolving
API.
These limitations have lead to the development of a variety of wrapping
systems. SWIG_ is probably the most popular package for the
integration of C/C++ and Python. A more recent development is SIP_,
which was specifically designed for interfacing Python with the Qt_
graphical user interface library. Both SWIG and SIP introduce their
own specialized languages for customizing inter-language bindings.
This has certain advantages, but having to deal with three different
languages (Python, C/C++ and the interface language) also introduces
practical and mental difficulties. The CXX_ package demonstrates an
interesting alternative. It shows that at least some parts of
Python's 'C' API can be wrapped and presented through a much more
user-friendly C++ interface. However, unlike SWIG and SIP, CXX does
not include support for wrapping C++ classes as new Python types.
The features and goals of Boost.Python_ overlap significantly with
many of these other systems. That said, Boost.Python attempts to
maximize convenience and flexibility without introducing a separate
wrapping language. Instead, it presents the user with a high-level
C++ interface for wrapping C++ classes and functions, managing much of
the complexity behind-the-scenes with static metaprogramming.
Boost.Python also goes beyond the scope of earlier systems by
providing:
* Support for C++ virtual functions that can be overridden in Python.
* Comprehensive lifetime management facilities for low-level C++
pointers and references.
* Support for organizing extensions as Python packages,
with a central registry for inter-language type conversions.
* A safe and convenient mechanism for tying into Python's powerful
serialization engine (pickle).
* Coherence with the rules for handling C++ lvalues and rvalues that
can only come from a deep understanding of both the Python and C++
type systems.
The key insight that sparked the development of Boost.Python is that
much of the boilerplate code in traditional extension modules could be
eliminated using C++ compile-time introspection. Each argument of a
wrapped C++ function must be extracted from a Python object using a
procedure that depends on the argument type. Similarly the function's
return type determines how the return value will be converted from C++
to Python. Of course argument and return types are part of each
function's type, and this is exactly the source from which
Boost.Python deduces most of the information required.
This approach leads to *user guided wrapping*: as much information is
extracted directly from the source code to be wrapped as is possible
within the framework of pure C++, and some additional information is
supplied explicitly by the user. Mostly the guidance is mechanical
and little real intervention is required. Because the interface
specification is written in the same full-featured language as the
code being exposed, the user has unprecedented power available when
she does need to take control.
.. _Python: http://www.python.org/
.. _SWIG: http://www.swig.org/
.. _SIP: http://www.riverbankcomputing.co.uk/sip/index.php
.. _Qt: http://www.trolltech.com/
.. _CXX: http://cxx.sourceforge.net/
.. _Boost.Python: http://www.boost.org/libs/python/doc
===========================
Boost.Python Design Goals
===========================
The primary goal of Boost.Python is to allow users to expose C++
classes and functions to Python using nothing more than a C++
compiler. In broad strokes, the user experience should be one of
directly manipulating C++ objects from Python.
However, it's also important not to translate all interfaces *too*
literally: the idioms of each language must be respected. For
example, though C++ and Python both have an iterator concept, they are
expressed very differently. Boost.Python has to be able to bridge the
interface gap.
It must be possible to insulate Python users from crashes resulting
from trivial misuses of C++ interfaces, such as accessing
already-deleted objects. By the same token the library should
insulate C++ users from low-level Python 'C' API, replacing
error-prone 'C' interfaces like manual reference-count management and
raw ``PyObject`` pointers with more-robust alternatives.
Support for component-based development is crucial, so that C++ types
exposed in one extension module can be passed to functions exposed in
another without loss of crucial information like C++ inheritance
relationships.
Finally, all wrapping must be *non-intrusive*, without modifying or
even seeing the original C++ source code. Existing C++ libraries have
to be wrappable by third parties who only have access to header files
and binaries.
==========================
Hello Boost.Python World
==========================
And now for a preview of Boost.Python, and how it improves on the raw
facilities offered by Python. Here's a function we might want to
expose::
char const* greet(unsigned x)
{
static char const* const msgs[] = { "hello", "Boost.Python", "world!" };
if (x > 2)
throw std::range_error("greet: index out of range");
return msgs[x];
}
To wrap this function in standard C++ using the Python 'C' API, we'd
need something like this::
extern "C" // all Python interactions use 'C' linkage and calling convention
{
// Wrapper to handle argument/result conversion and checking
PyObject* greet_wrap(PyObject* args, PyObject * keywords)
{
int x;
if (PyArg_ParseTuple(args, "i", &x)) // extract/check arguments
{
char const* result = greet(x); // invoke wrapped function
return PyString_FromString(result); // convert result to Python
}
return 0; // error occurred
}
// Table of wrapped functions to be exposed by the module
static PyMethodDef methods[] = {
{ "greet", greet_wrap, METH_VARARGS, "return one of 3 parts of a greeting" }
, { NULL, NULL, 0, NULL } // sentinel
};
// module initialization function
DL_EXPORT init_hello()
{
(void) Py_InitModule("hello", methods); // add the methods to the module
}
}
Now here's the wrapping code we'd use to expose it with Boost.Python::
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(hello)
{
def("greet", greet, "return one of 3 parts of a greeting");
}
and here it is in action::
>>> import hello
>>> for x in range(3):
... print hello.greet(x)
...
hello
Boost.Python
world!
Aside from the fact that the 'C' API version is much more verbose,
it's worth noting a few things that it doesn't handle correctly:
* The original function accepts an unsigned integer, and the Python
'C' API only gives us a way of extracting signed integers. The
Boost.Python version will raise a Python exception if we try to pass
a negative number to ``hello.greet``, but the other one will proceed
to do whatever the C++ implementation does when converting an
negative integer to unsigned (usually wrapping to some very large
number), and pass the incorrect translation on to the wrapped
function.
* That brings us to the second problem: if the C++ ``greet()``
function is called with a number greater than 2, it will throw an
exception. Typically, if a C++ exception propagates across the
boundary with code generated by a 'C' compiler, it will cause a
crash. As you can see in the first version, there's no C++
scaffolding there to prevent this from happening. Functions wrapped
by Boost.Python automatically include an exception-handling layer
which protects Python users by translating unhandled C++ exceptions
into a corresponding Python exception.
* A slightly more-subtle limitation is that the argument conversion
used in the Python 'C' API case can only get that integer ``x`` in
*one way*. PyArg_ParseTuple can't convert Python ``long`` objects
(arbitrary-precision integers) which happen to fit in an ``unsigned
int`` but not in a ``signed long``, nor will it ever handle a
wrapped C++ class with a user-defined implicit ``operator unsigned
int()`` conversion. Boost.Python's dynamic type conversion
registry allows users to add arbitrary conversion methods.
==================
Library Overview
==================
This section outlines some of the library's major features. Except as
neccessary to avoid confusion, details of library implementation are
omitted.
------------------
Exposing Classes
------------------
C++ classes and structs are exposed with a similarly-terse interface.
Given::
struct World
{
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
The following code will expose it in our extension module::
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(hello)
{
class_<World>("World")
.def("greet", &World::greet)
.def("set", &World::set)
;
}
Although this code has a certain pythonic familiarity, people
sometimes find the syntax bit confusing because it doesn't look like
most of the C++ code they're used to. All the same, this is just
standard C++. Because of their flexible syntax and operator
overloading, C++ and Python are great for defining domain-specific
(sub)languages
(DSLs), and that's what we've done in Boost.Python. To break it down::
class_<World>("World")
constructs an unnamed object of type ``class_<World>`` and passes
``"World"`` to its constructor. This creates a new-style Python class
called ``World`` in the extension module, and associates it with the
C++ type ``World`` in the Boost.Python type conversion registry. We
might have also written::
class_<World> w("World");
but that would've been more verbose, since we'd have to name ``w``
again to invoke its ``def()`` member function::
w.def("greet", &World::greet)
There's nothing special about the location of the dot for member
access in the original example: C++ allows any amount of whitespace on
either side of a token, and placing the dot at the beginning of each
line allows us to chain as many successive calls to member functions
as we like with a uniform syntax. The other key fact that allows
chaining is that ``class_<>`` member functions all return a reference
to ``*this``.
So the example is equivalent to::
class_<World> w("World");
w.def("greet", &World::greet);
w.def("set", &World::set);
It's occasionally useful to be able to break down the components of a
Boost.Python class wrapper in this way, but the rest of this article
will stick to the terse syntax.
For completeness, here's the wrapped class in use: ::
>>> import hello
>>> planet = hello.World()
>>> planet.set('howdy')
>>> planet.greet()
'howdy'
Constructors
============
Since our ``World`` class is just a plain ``struct``, it has an
implicit no-argument (nullary) constructor. Boost.Python exposes the
nullary constructor by default, which is why we were able to write: ::
>>> planet = hello.World()
However, well-designed classes in any language may require constructor
arguments in order to establish their invariants. Unlike Python,
where ``__init__`` is just a specially-named method, In C++
constructors cannot be handled like ordinary member functions. In
particular, we can't take their address: ``&World::World`` is an
error. The library provides a different interface for specifying
constructors. Given::
struct World
{
World(std::string msg); // added constructor
...
we can modify our wrapping code as follows::
class_<World>("World", init<std::string>())
...
of course, a C++ class may have additional constructors, and we can
expose those as well by passing more instances of ``init<...>`` to
``def()``::
class_<World>("World", init<std::string>())
.def(init<double, double>())
...
Boost.Python allows wrapped functions, member functions, and
constructors to be overloaded to mirror C++ overloading.
Data Members and Properties
===========================
Any publicly-accessible data members in a C++ class can be easily
exposed as either ``readonly`` or ``readwrite`` attributes::
class_<World>("World", init<std::string>())
.def_readonly("msg", &World::msg)
...
and can be used directly in Python: ::
>>> planet = hello.World('howdy')
>>> planet.msg
'howdy'
This does *not* result in adding attributes to the ``World`` instance
``__dict__``, which can result in substantial memory savings when
wrapping large data structures. In fact, no instance ``__dict__``
will be created at all unless attributes are explicitly added from
Python. Boost.Python owes this capability to the new Python 2.2 type
system, in particular the descriptor interface and ``property`` type.
In C++, publicly-accessible data members are considered a sign of poor
design because they break encapsulation, and style guides usually
dictate the use of "getter" and "setter" functions instead. In
Python, however, ``__getattr__``, ``__setattr__``, and since 2.2,
``property`` mean that attribute access is just one more
well-encapsulated syntactic tool at the programmer's disposal.
Boost.Python bridges this idiomatic gap by making Python ``property``
creation directly available to users. If ``msg`` were private, we
could still expose it as attribute in Python as follows::
class_<World>("World", init<std::string>())
.add_property("msg", &World::greet, &World::set)
...
The example above mirrors the familiar usage of properties in Python
2.2+: ::
>>> class World(object):
... __init__(self, msg):
... self.__msg = msg
... def greet(self):
... return self.__msg
... def set(self, msg):
... self.__msg = msg
... msg = property(greet, set)
Operator Overloading
====================
The ability to write arithmetic operators for user-defined types has
been a major factor in the success of both languages for numerical
computation, and the success of packages like NumPy_ attests to the
power of exposing operators in extension modules. Boost.Python
provides a concise mechanism for wrapping operator overloads. The
example below shows a fragment from a wrapper for the Boost rational
number library::
class_<rational<int> >("rational_int")
.def(init<int, int>()) // constructor, e.g. rational_int(3,4)
.def("numerator", &rational<int>::numerator)
.def("denominator", &rational<int>::denominator)
.def(-self) // __neg__ (unary minus)
.def(self + self) // __add__ (homogeneous)
.def(self * self) // __mul__
.def(self + int()) // __add__ (heterogenous)
.def(int() + self) // __radd__
...
The magic is performed using a simplified application of "expression
templates" [VELD1995]_, a technique originally developed for
optimization of high-performance matrix algebra expressions. The
essence is that instead of performing the computation immediately,
operators are overloaded to construct a type *representing* the
computation. In matrix algebra, dramatic optimizations are often
available when the structure of an entire expression can be taken into
account, rather than evaluating each operation "greedily".
Boost.Python uses the same technique to build an appropriate Python
method object based on expressions involving ``self``.
.. _NumPy: http://www.pfdubois.com/numpy/
Inheritance
===========
C++ inheritance relationships can be represented to Boost.Python by adding
an optional ``bases<...>`` argument to the ``class_<...>`` template
parameter list as follows::
class_<Derived, bases<Base1,Base2> >("Derived")
...
This has two effects:
1. When the ``class_<...>`` is created, Python type objects
corresponding to ``Base1`` and ``Base2`` are looked up in
Boost.Python's registry, and are used as bases for the new Python
``Derived`` type object, so methods exposed for the Python ``Base1``
and ``Base2`` types are automatically members of the ``Derived``
type. Because the registry is global, this works correctly even if
``Derived`` is exposed in a different module from either of its
bases.
2. C++ conversions from ``Derived`` to its bases are added to the
Boost.Python registry. Thus wrapped C++ methods expecting (a
pointer or reference to) an object of either base type can be
called with an object wrapping a ``Derived`` instance. Wrapped
member functions of class ``T`` are treated as though they have an
implicit first argument of ``T&``, so these conversions are
neccessary to allow the base class methods to be called for derived
objects.
Of course it's possible to derive new Python classes from wrapped C++
class instances. Because Boost.Python uses the new-style class
system, that works very much as for the Python built-in types. There
is one significant detail in which it differs: the built-in types
generally establish their invariants in their ``__new__`` function, so
that derived classes do not need to call ``__init__`` on the base
class before invoking its methods : ::
>>> class L(list):
... def __init__(self):
... pass
...
>>> L().reverse()
>>>
Because C++ object construction is a one-step operation, C++ instance
data cannot be constructed until the arguments are available, in the
``__init__`` function: ::
>>> class D(SomeBoostPythonClass):
... def __init__(self):
... pass
...
>>> D().some_boost_python_method()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: bad argument type for built-in operation
This happened because Boost.Python couldn't find instance data of type
``SomeBoostPythonClass`` within the ``D`` instance; ``D``'s ``__init__``
function masked construction of the base class. It could be corrected
by either removing ``D``'s ``__init__`` function or having it call
``SomeBoostPythonClass.__init__(...)`` explicitly.
Virtual Functions
=================
Deriving new types in Python from extension classes is not very
interesting unless they can be used polymorphically from C++. In
other words, Python method implementations should appear to override
the implementation of C++ virtual functions when called *through base
class pointers/references from C++*. Since the only way to alter the
behavior of a virtual function is to override it in a derived class,
the user must build a special derived class to dispatch a polymorphic
class' virtual functions::
//
// interface to wrap:
//
class Base
{
public:
virtual int f(std::string x) { return 42; }
virtual ~Base();
};
int calls_f(Base const& b, std::string x) { return b.f(x); }
//
// Wrapping Code
//
// Dispatcher class
struct BaseWrap : Base
{
// Store a pointer to the Python object
BaseWrap(PyObject* self_) : self(self_) {}
PyObject* self;
// Default implementation, for when f is not overridden
int f_default(std::string x) { return this->Base::f(x); }
// Dispatch implementation
int f(std::string x) { return call_method<int>(self, "f", x); }
};
...
def("calls_f", calls_f);
class_<Base, BaseWrap>("Base")
.def("f", &Base::f, &BaseWrap::f_default)
;
Now here's some Python code which demonstrates: ::
>>> class Derived(Base):
... def f(self, s):
... return len(s)
...
>>> calls_f(Base(), 'foo')
42
>>> calls_f(Derived(), 'forty-two')
9
Things to notice about the dispatcher class:
* The key element which allows overriding in Python is the
``call_method`` invocation, which uses the same global type
conversion registry as the C++ function wrapping does to convert its
arguments from C++ to Python and its return type from Python to C++.
* Any constructor signatures you wish to wrap must be replicated with
an initial ``PyObject*`` argument
* The dispatcher must store this argument so that it can be used to
invoke ``call_method``
* The ``f_default`` member function is needed when the function being
exposed is not pure virtual; there's no other way ``Base::f`` can be
called on an object of type ``BaseWrap``, since it overrides ``f``.
Deeper Reflection on the Horizon?
=================================
Admittedly, this formula is tedious to repeat, especially on a project
with many polymorphic classes. That it is neccessary reflects some
limitations in C++'s compile-time introspection capabilities: there's
no way to enumerate the members of a class and find out which are
virtual functions. At least one very promising project has been
started to write a front-end which can generate these dispatchers (and
other wrapping code) automatically from C++ headers.
Pyste_ is being developed by Bruno da Silva de Oliveira. It builds on
GCC_XML_, which generates an XML version of GCC's internal program
representation. Since GCC is a highly-conformant C++ compiler, this
ensures correct handling of the most-sophisticated template code and
full access to the underlying type system. In keeping with the
Boost.Python philosophy, a Pyste interface description is neither
intrusive on the code being wrapped, nor expressed in some unfamiliar
language: instead it is a 100% pure Python script. If Pyste is
successful it will mark a move away from wrapping everything directly
in C++ for many of our users. It will also allow us the choice to
shift some of the metaprogram code from C++ to Python. We expect that
soon, not only our users but the Boost.Python developers themselves
will be "thinking hybrid" about their own code.
.. _`GCC_XML`: http://www.gccxml.org/HTML/Index.html
.. _`Pyste`: http://www.boost.org/libs/python/pyste
---------------
Serialization
---------------
*Serialization* is the process of converting objects in memory to a
form that can be stored on disk or sent over a network connection. The
serialized object (most often a plain string) can be retrieved and
converted back to the original object. A good serialization system will
automatically convert entire object hierarchies. Python's standard
``pickle`` module is just such a system. It leverages the language's strong
runtime introspection facilities for serializing practically arbitrary
user-defined objects. With a few simple and unintrusive provisions this
powerful machinery can be extended to also work for wrapped C++ objects.
Here is an example::
#include <string>
struct World
{
World(std::string a_msg) : msg(a_msg) {}
std::string greet() const { return msg; }
std::string msg;
};
#include <boost/python.hpp>
using namespace boost::python;
struct World_picklers : pickle_suite
{
static tuple
getinitargs(World const& w) { return make_tuple(w.greet()); }
};
BOOST_PYTHON_MODULE(hello)
{
class_<World>("World", init<std::string>())
.def("greet", &World::greet)
.def_pickle(World_picklers())
;
}
Now let's create a ``World`` object and put it to rest on disk::
>>> import hello
>>> import pickle
>>> a_world = hello.World("howdy")
>>> pickle.dump(a_world, open("my_world", "w"))
In a potentially *different script* on a potentially *different
computer* with a potentially *different operating system*::
>>> import pickle
>>> resurrected_world = pickle.load(open("my_world", "r"))
>>> resurrected_world.greet()
'howdy'
Of course the ``cPickle`` module can also be used for faster
processing.
Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol
defined in the standard Python documentation. Like a __getinitargs__
function in Python, the pickle_suite's getinitargs() is responsible for
creating the argument tuple that will be use to reconstruct the pickled
object. The other elements of the Python pickling protocol,
__getstate__ and __setstate__ can be optionally provided via C++
getstate and setstate functions. C++'s static type system allows the
library to ensure at compile-time that nonsensical combinations of
functions (e.g. getstate without setstate) are not used.
Enabling serialization of more complex C++ objects requires a little
more work than is shown in the example above. Fortunately the
``object`` interface (see next section) greatly helps in keeping the
code manageable.
------------------
Object interface
------------------
Experienced 'C' language extension module authors will be familiar
with the ubiquitous ``PyObject*``, manual reference-counting, and the
need to remember which API calls return "new" (owned) references or
"borrowed" (raw) references. These constraints are not just
cumbersome but also a major source of errors, especially in the
presence of exceptions.
Boost.Python provides a class ``object`` which automates reference
counting and provides conversion to Python from C++ objects of
arbitrary type. This significantly reduces the learning effort for
prospective extension module writers.
Creating an ``object`` from any other type is extremely simple::
object s("hello, world"); // s manages a Python string
``object`` has templated interactions with all other types, with
automatic to-python conversions. It happens so naturally that it's
easily overlooked::
object ten_Os = 10 * s[4]; // -> "oooooooooo"
In the example above, ``4`` and ``10`` are converted to Python objects
before the indexing and multiplication operations are invoked.
The ``extract<T>`` class template can be used to convert Python objects
to C++ types::
double x = extract<double>(o);
If a conversion in either direction cannot be performed, an
appropriate exception is thrown at runtime.
The ``object`` type is accompanied by a set of derived types
that mirror the Python built-in types such as ``list``, ``dict``,
``tuple``, etc. as much as possible. This enables convenient
manipulation of these high-level types from C++::
dict d;
d["some"] = "thing";
d["lucky_number"] = 13;
list l = d.keys();
This almost looks and works like regular Python code, but it is pure
C++. Of course we can wrap C++ functions which accept or return
``object`` instances.
=================
Thinking hybrid
=================
Because of the practical and mental difficulties of combining
programming languages, it is common to settle a single language at the
outset of any development effort. For many applications, performance
considerations dictate the use of a compiled language for the core
algorithms. Unfortunately, due to the complexity of the static type
system, the price we pay for runtime performance is often a
significant increase in development time. Experience shows that
writing maintainable C++ code usually takes longer and requires *far*
more hard-earned working experience than developing comparable Python
code. Even when developers are comfortable working exclusively in
compiled languages, they often augment their systems by some type of
ad hoc scripting layer for the benefit of their users without ever
availing themselves of the same advantages.
Boost.Python enables us to *think hybrid*. Python can be used for
rapidly prototyping a new application; its ease of use and the large
pool of standard libraries give us a head start on the way to a
working system. If necessary, the working code can be used to
discover rate-limiting hotspots. To maximize performance these can
be reimplemented in C++, together with the Boost.Python bindings
needed to tie them back into the existing higher-level procedure.
Of course, this *top-down* approach is less attractive if it is clear
from the start that many algorithms will eventually have to be
implemented in C++. Fortunately Boost.Python also enables us to
pursue a *bottom-up* approach. We have used this approach very
successfully in the development of a toolbox for scientific
applications. The toolbox started out mainly as a library of C++
classes with Boost.Python bindings, and for a while the growth was
mainly concentrated on the C++ parts. However, as the toolbox is
becoming more complete, more and more newly added functionality can be
implemented in Python.
.. image:: python_cpp_mix.jpg
This figure shows the estimated ratio of newly added C++ and Python
code over time as new algorithms are implemented. We expect this
ratio to level out near 70% Python. Being able to solve new problems
mostly in Python rather than a more difficult statically typed
language is the return on our investment in Boost.Python. The ability
to access all of our code from Python allows a broader group of
developers to use it in the rapid development of new applications.
=====================
Development history
=====================
The first version of Boost.Python was developed in 2000 by Dave
Abrahams at Dragon Systems, where he was privileged to have Tim Peters
as a guide to "The Zen of Python". One of Dave's jobs was to develop
a Python-based natural language processing system. Since it was
eventually going to be targeting embedded hardware, it was always
assumed that the compute-intensive core would be rewritten in C++ to
optimize speed and memory footprint [#proto]_. The project also wanted to
test all of its C++ code using Python test scripts [#test]_. The only
tool we knew of for binding C++ and Python was SWIG_, and at the time
its handling of C++ was weak. It would be false to claim any deep
insight into the possible advantages of Boost.Python's approach at
this point. Dave's interest and expertise in fancy C++ template
tricks had just reached the point where he could do some real damage,
and Boost.Python emerged as it did because it filled a need and
because it seemed like a cool thing to try.
This early version was aimed at many of the same basic goals we've
described in this paper, differing most-noticeably by having a
slightly more cumbersome syntax and by lack of special support for
operator overloading, pickling, and component-based development.
These last three features were quickly added by Ullrich Koethe and
Ralf Grosse-Kunstleve [#feature]_, and other enthusiastic contributors arrived
on the scene to contribute enhancements like support for nested
modules and static member functions.
By early 2001 development had stabilized and few new features were
being added, however a disturbing new fact came to light: Ralf had
begun testing Boost.Python on pre-release versions of a compiler using
the EDG_ front-end, and the mechanism at the core of Boost.Python
responsible for handling conversions between Python and C++ types was
failing to compile. As it turned out, we had been exploiting a very
common bug in the implementation of all the C++ compilers we had
tested. We knew that as C++ compilers rapidly became more
standards-compliant, the library would begin failing on more
platforms. Unfortunately, because the mechanism was so central to the
functioning of the library, fixing the problem looked very difficult.
Fortunately, later that year Lawrence Berkeley and later Lawrence
Livermore National labs contracted with `Boost Consulting`_ for support
and development of Boost.Python, and there was a new opportunity to
address fundamental issues and ensure a future for the library. A
redesign effort began with the low level type conversion architecture,
building in standards-compliance and support for component-based
development (in contrast to version 1 where conversions had to be
explicitly imported and exported across module boundaries). A new
analysis of the relationship between the Python and C++ objects was
done, resulting in more intuitive handling for C++ lvalues and
rvalues.
The emergence of a powerful new type system in Python 2.2 made the
choice of whether to maintain compatibility with Python 1.5.2 easy:
the opportunity to throw away a great deal of elaborate code for
emulating classic Python classes alone was too good to pass up. In
addition, Python iterators and descriptors provided crucial and
elegant tools for representing similar C++ constructs. The
development of the generalized ``object`` interface allowed us to
further shield C++ programmers from the dangers and syntactic burdens
of the Python 'C' API. A great number of other features including C++
exception translation, improved support for overloaded functions, and
most significantly, CallPolicies for handling pointers and
references, were added during this period.
In October 2002, version 2 of Boost.Python was released. Development
since then has concentrated on improved support for C++ runtime
polymorphism and smart pointers. Peter Dimov's ingenious
``boost::shared_ptr`` design in particular has allowed us to give the
hybrid developer a consistent interface for moving objects back and
forth across the language barrier without loss of information. At
first, we were concerned that the sophistication and complexity of the
Boost.Python v2 implementation might discourage contributors, but the
emergence of Pyste_ and several other significant feature
contributions have laid those fears to rest. Daily questions on the
Python C++-sig and a backlog of desired improvements show that the
library is getting used. To us, the future looks bright.
.. _`EDG`: http://www.edg.com
=============
Conclusions
=============
Boost.Python achieves seamless interoperability between two rich and
complimentary language environments. Because it leverages template
metaprogramming to introspect about types and functions, the user
never has to learn a third syntax: the interface definitions are
written in concise and maintainable C++. Also, the wrapping system
doesn't have to parse C++ headers or represent the type system: the
compiler does that work for us.
Computationally intensive tasks play to the strengths of C++ and are
often impossible to implement efficiently in pure Python, while jobs
like serialization that are trivial in Python can be very difficult in
pure C++. Given the luxury of building a hybrid software system from
the ground up, we can approach design with new confidence and power.
===========
Citations
===========
.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report,
Vol. 7 No. 5 June 1995, pp. 26-31.
http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html
===========
Footnotes
===========
.. [#proto] In retrospect, it seems that "thinking hybrid" from the
ground up might have been better for the NLP system: the
natural component boundaries defined by the pure python
prototype turned out to be inappropriate for getting the
desired performance and memory footprint out of the C++ core,
which eventually caused some redesign overhead on the Python
side when the core was moved to C++.
.. [#test] We also have some reservations about driving all C++
testing through a Python interface, unless that's the only way
it will be ultimately used. Any transition across language
boundaries with such different object models can inevitably
mask bugs.
.. [#feature] These features were expressed very differently in v1 of
Boost.Python

View File

@@ -0,0 +1,908 @@
.. This is a comment. Note how any initial comments are moved by
transforms to after the document title, subtitle, and docinfo.
.. Need intro and conclusion
.. Exposing classes
.. Constructors
.. Overloading
.. Properties and data members
.. Inheritance
.. Operators and Special Functions
.. Virtual Functions
.. Call Policies
++++++++++++++++++++++++++++++++++++++++++++++
Introducing Boost.Python (Extended Abstract)
++++++++++++++++++++++++++++++++++++++++++++++
.. bibliographic fields (which also require a transform):
:Author: David Abrahams
:Address: 45 Walnut Street
Somerville, MA 02143
:Contact: dave@boost-consulting.com
:organization: `Boost Consulting`_
:date: $Date$
:status: This is a "work in progress"
:version: 1
:copyright: Copyright David Abrahams 2002. All rights reserved
:Dedication:
For my girlfriend, wife, and partner Luann
:abstract:
This paper describes the Boost.Python library, a system for
C++/Python interoperability.
.. meta::
:keywords: Boost,python,Boost.Python,C++
:description lang=en: C++/Python interoperability with Boost.Python
.. contents:: Table of Contents
.. section-numbering::
.. _`Boost Consulting`: http://www.boost-consulting.com
==============
Introduction
==============
Python and C++ are in many ways as different as two languages could
be: while C++ is usually compiled to machine-code, Python is
interpreted. Python's dynamic type system is often cited as the
foundation of its flexibility, while in C++ static typing is the
cornerstone of its efficiency. C++ has an intricate and difficult
meta-language to support compile-time polymorphism, while Python is
a uniform language with convenient runtime polymorphism.
Yet for many programmers, these very differences mean that Python and
C++ complement one another perfectly. Performance bottlenecks in
Python programs can be rewritten in C++ for maximal speed, and
authors of powerful C++ libraries choose Python as a middleware
language for its flexible system integration capabilities.
Furthermore, the surface differences mask some strong similarities:
* 'C'-family control structures (if, while, for...)
* Support for object-orientation, functional programming, and generic
programming (these are both *multi-paradigm* programming languages.)
* Comprehensive operator overloading facilities, recognizing the
importance of syntactic variability for readability and
expressivity.
* High-level concepts such as collections and iterators.
* High-level encapsulation facilities (C++: namespaces, Python: modules)
to support the design of re-usable libraries.
* Exception-handling for effective management of error conditions.
* C++ idioms in common use, such as handle/body classes and
reference-counted smart pointers mirror Python reference semantics.
Python provides a rich 'C' API for writers of 'C' extension modules.
Unfortunately, using this API directly for exposing C++ type and
function interfaces to Python is much more tedious than it should be.
This is mainly due to the limitations of the 'C' language. Compared to
C++ and Python, 'C' has only very rudimentary abstraction facilities.
Support for exception-handling is completely missing. One important
undesirable consequence is that 'C' extension module writers are
required to manually manage Python reference counts. Another unpleasant
consequence is a very high degree of repetition of similar code in 'C'
extension modules. Of course highly redundant code does not only cause
frustration for the module writer, but is also very difficult to
maintain.
The limitations of the 'C' API have lead to the development of a
variety of wrapping systems. SWIG_ is probably the most popular package
for the integration of C/C++ and Python. A more recent development is
the SIP_ package, which is specifically designed for interfacing Python
with the Qt_ graphical user interface library. Both SWIG and SIP
introduce a new specialized language for defining the inter-language
bindings. Of course being able to use a specialized language has
advantages, but having to deal with three different languages (Python,
C/C++ and the interface language) also introduces practical and mental
difficulties. The CXX_ package demonstrates an interesting alternative.
It shows that at least some parts of Python's 'C' API can be wrapped
and presented through a much more user-friendly C++ interface. However,
unlike SWIG and SIP, CXX does not include support for wrapping C++
classes as new Python types. CXX is also no longer actively developed.
In some respects Boost.Python combines ideas from SWIG and SIP with
ideas from CXX. Like SWIG and SIP, Boost.Python is a system for
wrapping C++ classes as new Python "built-in" types, and C/C++
functions as Python functions. Like CXX, Boost.Python presents Python's
'C' API through a C++ interface. Boost.Python goes beyond the scope of
other systems with the unique support for C++ virtual functions that
are overrideable in Python, support for organizing extensions as Python
packages with a central registry for inter-language type conversions,
and a convenient mechanism for tying into Python's serialization engine
(pickle). Importantly, all this is achieved without introducing a new
syntax. Boost.Python leverages the power of C++ meta-programming
techniques to introspect about the C++ type system, and presents a
simple, IDL-like C++ interface for exposing C/C++ code in extension
modules. Boost.Python is a pure C++ library, the inter-language
bindings are defined in pure C++, and other than a C++ compiler only
Python itself is required to get started with Boost.Python. Last but
not least, Boost.Python is an unrestricted open source library. There
are no strings attached even for commercial applications.
.. _SWIG: http://www.swig.org/
.. _SIP: http://www.riverbankcomputing.co.uk/sip/index.php
.. _Qt: http://www.trolltech.com/
.. _CXX: http://cxx.sourceforge.net/
===========================
Boost.Python Design Goals
===========================
The primary goal of Boost.Python is to allow users to expose C++
classes and functions to Python using nothing more than a C++
compiler. In broad strokes, the user experience should be one of
directly manipulating C++ objects from Python.
However, it's also important not to translate all interfaces *too*
literally: the idioms of each language must be respected. For
example, though C++ and Python both have an iterator concept, they are
expressed very differently. Boost.Python has to be able to bridge the
interface gap.
It must be possible to insulate Python users from crashes resulting
from trivial misuses of C++ interfaces, such as accessing
already-deleted objects. By the same token the library should
insulate C++ users from low-level Python 'C' API, replacing
error-prone 'C' interfaces like manual reference-count management and
raw ``PyObject`` pointers with more-robust alternatives.
Support for component-based development is crucial, so that C++ types
exposed in one extension module can be passed to functions exposed in
another without loss of crucial information like C++ inheritance
relationships.
Finally, all wrapping must be *non-intrusive*, without modifying or
even seeing the original C++ source code. Existing C++ libraries have
to be wrappable by third parties who only have access to header files
and binaries.
==========================
Hello Boost.Python World
==========================
And now for a preview of Boost.Python, and how it improves on the raw
facilities offered by Python. Here's a function we might want to
expose::
char const* greet(unsigned x)
{
static char const* const msgs[] = { "hello", "Boost.Python", "world!" };
if (x > 2)
throw std::range_error("greet: index out of range");
return msgs[x];
}
To wrap this function in standard C++ using the Python 'C' API, we'd
need something like this::
extern "C" // all Python interactions use 'C' linkage and calling convention
{
// Wrapper to handle argument/result conversion and checking
PyObject* greet_wrap(PyObject* args, PyObject * keywords)
{
int x;
if (PyArg_ParseTuple(args, "i", &x)) // extract/check arguments
{
char const* result = greet(x); // invoke wrapped function
return PyString_FromString(result); // convert result to Python
}
return 0; // error occurred
}
// Table of wrapped functions to be exposed by the module
static PyMethodDef methods[] = {
{ "greet", greet_wrap, METH_VARARGS, "return one of 3 parts of a greeting" }
, { NULL, NULL, 0, NULL } // sentinel
};
// module initialization function
DL_EXPORT init_hello()
{
(void) Py_InitModule("hello", methods); // add the methods to the module
}
}
Now here's the wrapping code we'd use to expose it with Boost.Python::
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(hello)
{
def("greet", greet, "return one of 3 parts of a greeting");
}
and here it is in action::
>>> import hello
>>> for x in range(3):
... print hello.greet(x)
...
hello
Boost.Python
world!
Aside from the fact that the 'C' API version is much more verbose than
the BPL one, it's worth noting that it doesn't handle a few things
correctly:
* The original function accepts an unsigned integer, and the Python
'C' API only gives us a way of extracting signed integers. The
Boost.Python version will raise a Python exception if we try to pass
a negative number to ``hello.greet``, but the other one will proceed
to do whatever the C++ implementation does when converting an
negative integer to unsigned (usually wrapping to some very large
number), and pass the incorrect translation on to the wrapped
function.
* That brings us to the second problem: if the C++ ``greet()``
function is called with a number greater than 2, it will throw an
exception. Typically, if a C++ exception propagates across the
boundary with code generated by a 'C' compiler, it will cause a
crash. As you can see in the first version, there's no C++
scaffolding there to prevent this from happening. Functions wrapped
by Boost.Python automatically include an exception-handling layer
which protects Python users by translating unhandled C++ exceptions
into a corresponding Python exception.
* A slightly more-subtle limitation is that the argument conversion
used in the Python 'C' API case can only get that integer ``x`` in
*one way*. PyArg_ParseTuple can't convert Python ``long`` objects
(arbitrary-precision integers) which happen to fit in an ``unsigned
int`` but not in a ``signed long``, nor will it ever handle a
wrapped C++ class with a user-defined implicit ``operator unsigned
int()`` conversion. The BPL's dynamic type conversion registry
allows users to add arbitrary conversion methods.
==================
Library Overview
==================
This section outlines some of the library's major features. Except as
neccessary to avoid confusion, details of library implementation are
omitted.
-------------------------------------------
The fundamental type-conversion mechanism
-------------------------------------------
XXX This needs to be rewritten.
Every argument of every wrapped function requires some kind of
extraction code to convert it from Python to C++. Likewise, the
function return value has to be converted from C++ to Python.
Appropriate Python exceptions must be raised if the conversion fails.
Argument and return types are part of the function's type, and much of
this tedium can be relieved if the wrapping system can extract that
information through introspection.
Passing a wrapped C++ derived class instance to a C++ function
accepting a pointer or reference to a base class requires knowledge of
the inheritance relationship and how to translate the address of a base
class into that of a derived class.
------------------
Exposing Classes
------------------
C++ classes and structs are exposed with a similarly-terse interface.
Given::
struct World
{
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
The following code will expose it in our extension module::
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(hello)
{
class_<World>("World")
.def("greet", &World::greet)
.def("set", &World::set)
;
}
Although this code has a certain pythonic familiarity, people
sometimes find the syntax bit confusing because it doesn't look like
most of the C++ code they're used to. All the same, this is just
standard C++. Because of their flexible syntax and operator
overloading, C++ and Python are great for defining domain-specific
(sub)languages
(DSLs), and that's what we've done in BPL. To break it down::
class_<World>("World")
constructs an unnamed object of type ``class_<World>`` and passes
``"World"`` to its constructor. This creates a new-style Python class
called ``World`` in the extension module, and associates it with the
C++ type ``World`` in the BPL type conversion registry. We might have
also written::
class_<World> w("World");
but that would've been more verbose, since we'd have to name ``w``
again to invoke its ``def()`` member function::
w.def("greet", &World::greet)
There's nothing special about the location of the dot for member
access in the original example: C++ allows any amount of whitespace on
either side of a token, and placing the dot at the beginning of each
line allows us to chain as many successive calls to member functions
as we like with a uniform syntax. The other key fact that allows
chaining is that ``class_<>`` member functions all return a reference
to ``*this``.
So the example is equivalent to::
class_<World> w("World");
w.def("greet", &World::greet);
w.def("set", &World::set);
It's occasionally useful to be able to break down the components of a
Boost.Python class wrapper in this way, but the rest of this paper
will tend to stick to the terse syntax.
For completeness, here's the wrapped class in use:
>>> import hello
>>> planet = hello.World()
>>> planet.set('howdy')
>>> planet.greet()
'howdy'
Constructors
============
Since our ``World`` class is just a plain ``struct``, it has an
implicit no-argument (nullary) constructor. Boost.Python exposes the
nullary constructor by default, which is why we were able to write:
>>> planet = hello.World()
However, well-designed classes in any language may require constructor
arguments in order to establish their invariants. Unlike Python,
where ``__init__`` is just a specially-named method, In C++
constructors cannot be handled like ordinary member functions. In
particular, we can't take their address: ``&World::World`` is an
error. The library provides a different interface for specifying
constructors. Given::
struct World
{
World(std::string msg); // added constructor
...
we can modify our wrapping code as follows::
class_<World>("World", init<std::string>())
...
of course, a C++ class may have additional constructors, and we can
expose those as well by passing more instances of ``init<...>`` to
``def()``::
class_<World>("World", init<std::string>())
.def(init<double, double>())
...
Boost.Python allows wrapped functions, member functions, and
constructors to be overloaded to mirror C++ overloading.
Data Members and Properties
===========================
Any publicly-accessible data members in a C++ class can be easily
exposed as either ``readonly`` or ``readwrite`` attributes::
class_<World>("World", init<std::string>())
.def_readonly("msg", &World::msg)
...
and can be used directly in Python:
>>> planet = hello.World('howdy')
>>> planet.msg
'howdy'
This does *not* result in adding attributes to the ``World`` instance
``__dict__``, which can result in substantial memory savings when
wrapping large data structures. In fact, no instance ``__dict__``
will be created at all unless attributes are explicitly added from
Python. BPL owes this capability to the new Python 2.2 type system,
in particular the descriptor interface and ``property`` type.
In C++, publicly-accessible data members are considered a sign of poor
design because they break encapsulation, and style guides usually
dictate the use of "getter" and "setter" functions instead. In
Python, however, ``__getattr__``, ``__setattr__``, and since 2.2,
``property`` mean that attribute access is just one more
well-encapsulated syntactic tool at the programmer's disposal. BPL
bridges this idiomatic gap by making Python ``property`` creation
directly available to users. So if ``msg`` were private, we could
still expose it as attribute in Python as follows::
class_<World>("World", init<std::string>())
.add_property("msg", &World::greet, &World::set)
...
The example above mirrors the familiar usage of properties in Python
2.2+:
>>> class World(object):
... __init__(self, msg):
... self.__msg = msg
... def greet(self):
... return self.__msg
... def set(self, msg):
... self.__msg = msg
... msg = property(greet, set)
Operators and Special Functions
===============================
The ability to write arithmetic operators for user-defined types that
C++ and Python both allow the definition of has been a major factor in
the popularity of both languages for scientific computing. The
success of packages like NumPy attests to the power of exposing
operators in extension modules. In this example we'll wrap a class
representing a position in a large file::
class FilePos { /*...*/ };
// Linear offset
FilePos operator+(FilePos, int);
FilePos operator+(int, FilePos);
FilePos operator-(FilePos, int);
// Distance between two FilePos objects
int operator-(FilePos, FilePos);
// Offset with assignment
FilePos& operator+=(FilePos&, int);
FilePos& operator-=(FilePos&, int);
// Comparison
bool operator<(FilePos, FilePos);
The wrapping code looks like this::
class_<FilePos>("FilePos")
.def(self + int()) // __add__
.def(int() + self) // __radd__
.def(self - int()) // __sub__
.def(self - self) // __sub__
.def(self += int()) // __iadd__
.def(self -= int()) // __isub__
.def(self < self); // __lt__
;
The magic is performed using a simplified application of "expression
templates" [VELD1995]_, a technique originally developed by for
optimization of high-performance matrix algebra expressions. The
essence is that instead of performing the computation immediately,
operators are overloaded to construct a type *representing* the
computation. In matrix algebra, dramatic optimizations are often
available when the structure of an entire expression can be taken into
account, rather than processing each operation "greedily".
Boost.Python uses the same technique to build an appropriate Python
callable object based on an expression involving ``self``, which is
then added to the class.
Inheritance
===========
C++ inheritance relationships can be represented to Boost.Python by adding
an optional ``bases<...>`` argument to the ``class_<...>`` template
parameter list as follows::
class_<Derived, bases<Base1,Base2> >("Derived")
...
This has two effects:
1. When the ``class_<...>`` is created, Python type objects
corresponding to ``Base1`` and ``Base2`` are looked up in the BPL
registry, and are used as bases for the new Python ``Derived`` type
object [#mi]_, so methods exposed for the Python ``Base1`` and
``Base2`` types are automatically members of the ``Derived`` type.
Because the registry is global, this works correctly even if
``Derived`` is exposed in a different module from either of its
bases.
2. C++ conversions from ``Derived`` to its bases are added to the
Boost.Python registry. Thus wrapped C++ methods expecting (a
pointer or reference to) an object of either base type can be
called with an object wrapping a ``Derived`` instance. Wrapped
member functions of class ``T`` are treated as though they have an
implicit first argument of ``T&``, so these conversions are
neccessary to allow the base class methods to be called for derived
objects.
Of course it's possible to derive new Python classes from wrapped C++
class instances. Because Boost.Python uses the new-style class
system, that works very much as for the Python built-in types. There
is one significant detail in which it differs: the built-in types
generally establish their invariants in their ``__new__`` function, so
that derived classes do not need to call ``__init__`` on the base
class before invoking its methods :
>>> class L(list):
... def __init__(self):
... pass
...
>>> L().reverse()
>>>
Because C++ object construction is a one-step operation, C++ instance
data cannot be constructed until the arguments are available, in the
``__init__`` function:
>>> class D(SomeBPLClass):
... def __init__(self):
... pass
...
>>> D().some_bpl_method()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: bad argument type for built-in operation
This happened because Boost.Python couldn't find instance data of type
``SomeBPLClass`` within the ``D`` instance; ``D``'s ``__init__``
function masked construction of the base class. It could be corrected
by either removing ``D``'s ``__init__`` function or having it call
``SomeBPLClass.__init__(...)`` explicitly.
Virtual Functions
=================
Deriving new types in Python from extension classes is not very
interesting unless they can be used polymorphically from C++. In
other words, Python method implementations should appear to override
the implementation of C++ virtual functions when called *through base
class pointers/references from C++*. Since the only way to alter the
behavior of a virtual function is to override it in a derived class,
the user must build a special derived class to dispatch a polymorphic
class' virtual functions::
//
// interface to wrap:
//
class Base
{
public:
virtual int f(std::string x) { return 42; }
virtual ~Base();
};
int calls_f(Base const& b, std::string x) { return b.f(x); }
//
// Wrapping Code
//
// Dispatcher class
struct BaseWrap : Base
{
// Store a pointer to the Python object
BaseWrap(PyObject* self_) : self(self_) {}
PyObject* self;
// Default implementation, for when f is not overridden
int f_default(std::string x) { return this->Base::f(x); }
// Dispatch implementation
int f(std::string x) { return call_method<int>(self, "f", x); }
};
...
def("calls_f", calls_f);
class_<Base, BaseWrap>("Base")
.def("f", &Base::f, &BaseWrap::f_default)
;
Now here's some Python code which demonstrates:
>>> class Derived(Base):
... def f(self, s):
... return len(s)
...
>>> calls_f(Base(), 'foo')
42
>>> calls_f(Derived(), 'forty-two')
9
Things to notice about the dispatcher class:
* The key element which allows overriding in Python is the
``call_method`` invocation, which uses the same global type
conversion registry as the C++ function wrapping does to convert its
arguments from C++ to Python and its return type from Python to C++.
* Any constructor signatures you wish to wrap must be replicated with
an initial ``PyObject*`` argument
* The dispatcher must store this argument so that it can be used to
invoke ``call_method``
* The ``f_default`` member function is needed when the function being
exposed is not pure virtual; there's no other way ``Base::f`` can be
called on an object of type ``BaseWrap``, since it overrides ``f``.
Admittedly, this formula is tedious to repeat, especially on a project
with many polymorphic classes; that it is neccessary reflects
limitations in C++'s compile-time reflection capabilities. Several
efforts are underway to write front-ends for Boost.Python which can
generate these dispatchers (and other wrapping code) automatically.
If these are successful it will mark a move away from wrapping
everything directly in pure C++ for many of our users.
---------------
Serialization
---------------
*Serialization* is the process of converting objects in memory to a
form that can be stored on disk or sent over a network connection. The
serialized object (most often a plain string) can be retrieved and
converted back to the original object. A good serialization system will
automatically convert entire object hierarchies. Python's standard
``pickle`` module is such a system. It leverages the language's strong
runtime introspection facilities for serializing practically arbitrary
user-defined objects. With a few simple and unintrusive provisions this
powerful machinery can be extended to also work for wrapped C++ objects.
Here is an example::
#include <string>
struct World
{
World(std::string a_msg) : msg(a_msg) {}
std::string greet() const { return msg; }
std::string msg;
};
#include <boost/python.hpp>
using namespace boost::python;
struct World_picklers : pickle_suite
{
static tuple
getinitargs(World const& w) { return make_tuple(w.greet()); }
};
BOOST_PYTHON_MODULE(hello)
{
class_<World>("World", init<std::string>())
.def("greet", &World::greet)
.def_pickle(World_picklers())
;
}
Now let's create a ``World`` object and put it to rest on disk::
>>> import hello
>>> import pickle
>>> a_world = hello.World("howdy")
>>> pickle.dump(a_world, open("my_world", "w"))
In a potentially *different script* on a potentially *different
computer* with a potentially *different operating system*::
>>> import pickle
>>> resurrected_world = pickle.load(open("my_world", "r"))
>>> resurrected_world.greet()
'howdy'
Of course the ``cPickle`` module can also be used for faster
processing.
Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol
defined in the standard Python documentation. There is a one-to-one
correspondence between the standard pickling methods (``__getinitargs__``,
``__getstate__``, ``__setstate__``) and the functions defined by the
user in the class derived from ``pickle_suite`` (``getinitargs``,
``getstate``, ``setstate``). The ``class_::def_pickle()`` member function
is used to establish the Python bindings for all user-defined functions
simultaneously. Correct signatures for these functions are enforced at
compile time. Non-sensical combinations of the three pickle functions
are also rejected at compile time. These measures are designed to
help the user in avoiding obvious errors.
Enabling serialization of more complex C++ objects requires a little
more work than is shown in the example above. Fortunately the
``object`` interface (see next section) greatly helps in keeping the
code manageable.
------------------
Object interface
------------------
Experienced extension module authors will be familiar with the 'C' view
of Python objects, the ubiquitous ``PyObject*``. Most if not all Python
'C' API functions involve ``PyObject*`` as arguments or return type. A
major complication is the raw reference counting interface presented to
the 'C' programmer. E.g. some API functions return *new references* and
others return *borrowed references*. It is up to the extension module
writer to properly increment and decrement reference counts. This
quickly becomes cumbersome and error prone, especially if there are
multiple execution paths.
Boost.Python provides a type ``object`` which is essentially a high
level wrapper around ``PyObject*``. ``object`` automates reference
counting as much as possible. It also provides the facilities for
converting arbitrary C++ types to Python objects and vice versa.
This significantly reduces the learning effort for prospective
extension module writers.
Creating an ``object`` from any other type is extremely simple::
object o(3);
``object`` has templated interactions with all other types, with
automatic to-python conversions. It happens so naturally that it's
easily overlooked.
The ``extract<T>`` class template can be used to convert Python objects
to C++ types::
double x = extract<double>(o);
All registered user-defined conversions are automatically accessible
through the ``object`` interface. With reference to the ``World`` class
defined in previous examples::
object as_python_object(World("howdy"));
World back_as_c_plus_plus_object = extract<World>(as_python_object);
If a C++ type cannot be converted to a Python object an appropriate
exception is thrown at runtime. Similarly, an appropriate exception is
thrown if a C++ type cannot be extracted from a Python object.
``extract<T>`` provides facilities for avoiding exceptions if this is
desired.
The ``object::attr()`` member function is available for accessing
and manipulating attributes of Python objects. For example::
object planet(World());
planet.attr("set")("howdy");
``planet.attr("set")`` returns a callable ``object``. ``"howdy"`` is
converted to a Python string object which is then passed as an argument
to the ``set`` method.
The ``object`` type is accompanied by a set of derived types
that mirror the Python built-in types such as ``list``, ``dict``,
``tuple``, etc. as much as possible. This enables convenient
manipulation of these high-level types from C++::
dict d;
d["some"] = "thing";
d["lucky_number"] = 13;
list l = d.keys();
This almost looks and works like regular Python code, but it is pure C++.
=================
Thinking hybrid
=================
For many applications runtime performance considerations are very
important. This is particularly true for most scientific applications.
Often the performance considerations dictate the use of a compiled
language for the core algorithms. Traditionally the decision to use a
particular programming language is an exclusive one. Because of the
practical and mental difficulties of combining different languages many
systems are written in just one language. This is quite unfortunate
because the price payed for runtime performance is typically a
significant overhead due to static typing. For example, our experience
shows that developing maintainable C++ code is typically much more
time-consuming and requires much more hard-earned working experience
than developing useful Python code. A related observation is that many
compiled packages are augmented by some type of rudimentary scripting
layer. These ad hoc solutions clearly show that many times a compiled
language alone does not get the job done. On the other hand it is also
clear that a pure Python implementation is too slow for numerically
intensive production code.
Boost.Python enables us to *think hybrid* when developing new
applications. Python can be used for rapidly prototyping a
new application. Python's ease of use and the large pool of standard
libraries give us a head start on the way to a first working system. If
necessary, the working procedure can be used to discover the
rate-limiting algorithms. To maximize performance these can be
reimplemented in C++, together with the Boost.Python bindings needed to
tie them back into the existing higher-level procedure.
Of course, this *top-down* approach is less attractive if it is clear
from the start that many algorithms will eventually have to be
implemented in a compiled language. Fortunately Boost.Python also
enables us to pursue a *bottom-up* approach. We have used this approach
very successfully in the development of a toolbox for scientific
applications (scitbx) that we will describe elsewhere. The toolbox
started out mainly as a library of C++ classes with Boost.Python
bindings, and for a while the growth was mainly concentrated on the C++
parts. However, as the toolbox is becoming more complete, more and more
newly added functionality can be implemented in Python. We expect this
trend to continue, as illustrated qualitatively in this figure:
.. image:: python_cpp_mix.png
This figure shows the ratio of newly added C++ and Python code over
time as new algorithms are implemented. We expect this ratio to level
out near 70% Python. The increasing ability to solve new problems
mostly with the easy-to-use Python language rather than a necessarily
more arcane statically typed language is the return on the investment
of learning how to use Boost.Python. The ability to solve some problems
entirely using only Python will enable a larger group of people to
participate in the rapid development of new applications.
=============
Conclusions
=============
The examples in this paper illustrate that Boost.Python enables
seamless interoperability between C++ and Python. Importantly, this is
achieved without introducing a third syntax: the Python/C++ interface
definitions are written in pure C++. This avoids any problems with
parsing the C++ code to be interfaced to Python, yet the interface
definitions are concise and maintainable. Freed from most of the
development-time penalties of crossing a language boundary, software
designers can take full advantage of two rich and complimentary
language environments. In practice it turns out that some things are
very difficult to do with pure Python/C (e.g. an efficient array
library with an intuitive interface in the compiled language) and
others are very difficult to do with pure C++ (e.g. serialization).
If one has the luxury of being able to design a software system as a
hybrid system from the ground up there are many new ways of avoiding
road blocks in one language or the other.
.. I'm not ready to give up on all of this quite yet
.. Perhaps one day we'll have a language with the simplicity and
expressive power of Python and the compile-time muscle of C++. Being
able to take advantage of all of these facilities without paying the
mental and development-time penalties of crossing a language barrier
would bring enormous benefits. Until then, interoperability tools
like Boost.Python can help lower the barrier and make the benefits of
both languages more accessible to both communities.
===========
Footnotes
===========
.. [#mi] For hard-core new-style class/extension module writers it is
worth noting that the normal requirement that all extension classes
with data form a layout-compatible single-inheritance chain is
lifted for Boost.Python extension classes. Clearly, either
``Base1`` or ``Base2`` has to occupy a different offset in the
``Derived`` class instance. This is possible because the wrapped
part of BPL extension class instances is never assumed to have a
fixed offset within the wrapper.
===========
Citations
===========
.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report,
Vol. 7 No. 5 June 1995, pp. 26-31.
http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html

View File

@@ -0,0 +1,188 @@
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date$
:version: $Revision$
:copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
*/
.first {
margin-top: 0 }
.last {
margin-bottom: 0 }
a.toc-backref {
text-decoration: none ;
color: black }
dd {
margin-bottom: 0.5em }
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em }
div.footer, div.header {
font-size: smaller }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr {
width: 75% }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
pre.line-block {
font-family: serif ;
font-size: 100% }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
background-color: #eeeeee }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option-argument {
font-style: italic }
span.pre {
white-space: pre }
span.problematic {
color: red }
table {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.citation {
border-left: solid thin gray ;
padding-left: 0.5ex }
table.docinfo {
margin: 2em 4em }
table.footnote {
border-left: solid thin black ;
padding-left: 0.5ex }
td, th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
th.docinfo-name, th.field-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap }
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
font-size: 100% }
tt {
background-color: #eeeeee }
ul.auto-toc {
list-style-type: none }

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -3,7 +3,7 @@
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="boost.css">
@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="index.html">Boost.Python</a></h1>
<h2 align="center">Building and Testing</h2>
</td>
@@ -39,8 +39,16 @@
<dl class="index">
<dt><a href="#configuration">Configuration</a></dt>
<dt><a href="#cygwin_configuration">Configuration for Cygwin GCC
from a Windows prompt</a></dt>
<dt><a href="#results">Results</a></dt>
<dt><a href="#cygwin">Notes for Cygwin GCC Users</a></dt>
<dt><a href="#mingw">Notes for MinGW (and Cygwin with -mno-cygwin)
GCC Users</a></dt>
<dt><a href="#testing">Testing</a></dt>
</dl>
</dd>
@@ -48,24 +56,33 @@
<dt><a href="#building_ext">Building your Extension Module</a></dt>
<dt><a href="#variants">Build Variants</a></dt>
<dt><a href="#VisualStudio">Building Using the Microsoft Visual Studio
IDE</a></dt>
</dl>
<hr>
<h2><a name="requirements">Requirements</a></h2>
Boost.Python requires <a href="http://www.python.org">Python</a> 2.2 or
later.
<b>Boost.Python</b> version 2 requires <a href=
"http://www.python.org/2.2">Python 2.2</a> <i>or <a href=
"http://www.python.org">newer</a></i>. An unsupported archive of
Boost.Python version 1, which works with versions of Python since 1.5.2,
is available <a href="../build/python_v1.zip">here</a>.
<h2><a name="building">Building Boost.Python</a></h2>
<p>Every Boost.Python extension module must be linked with the
<code>boost_python</code> shared library. To build
<code>boost_python</code>, use <a href=
"../../../tools/build/index.html">Boost.Build</a> in the usual way from
the <code>libs/python/build</code> subdirectory of your boost
<p>Normally, Boost.Python extension modules must be linked with the
<code>boost_python</code> shared library. In special circumstances you
may want to link to a static version of the <code>boost_python</code>
library, but if multiple Boost.Python extension modules are used
together, it will prevent sharing of types across extension modules, and
consume extra code space. To build <code>boost_python</code>, use <a
href="../../../tools/build/v1/build_system.htm">Boost.Build</a> in the usual way
from the <code>libs/python/build</code> subdirectory of your boost
installation (if you have already built boost from the top level this may
have no effect, since the work is already done).</p>
<h3><a name="configuration">Configuration</a></h3>
<h3><a name="configuration">Basic Configuration</a></h3>
You may need to configure the following variables to point Boost.Build at
your Python installation:
@@ -108,7 +125,8 @@
<td>path to Python <code>#include</code> directories</td>
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
<td>Autoconfigured from <code>PYTHON_ROOT</code>. Try the default
before attempting to set it yourself.</td>
</tr>
<tr>
@@ -116,53 +134,101 @@
<td>path to Python library object.</td>
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
</tr>
<tr>
<td><code>PYTHON_STDLIB_PATH</code></td>
<td>path to Python standard library modules</td>
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
</tr>
<tr>
<td><code>CYGWIN_ROOT</code></td>
<td>path to the user's Cygwin installation</td>
<td>
</td>
<td><a href="http://www.cygwin.com">Cygwin</a> only. This and the
following two settings are useful when building with multiple
toolsets on Windows, since Cygwin requires a different build of
Python.</td>
</tr>
<tr>
<td><code>GCC_PYTHON_ROOT</code></td>
<td>path to the user's Cygwin Python installation</td>
<td><code>$(CYGWIN_ROOT)/usr/local</code></td>
<td><a href="http://www.cygwin.com">Cygwin</a> only</td>
</tr>
<tr>
<td><code>GCC_DEBUG_PYTHON_ROOT</code></td>
<td>path to the user's Cygwin <code><a href=
"#variants">pydebug</a></code> build</td>
<td><code>$(CYGWIN_ROOT)/usr/local/pydebug</code></td>
<td><a href="http://www.cygwin.com">Cygwin</a> only</td>
<td>Autoconfigured from <code>PYTHON_ROOT</code>. Try the default
before attempting to set it yourself.</td>
</tr>
</table>
<h3><a name="cygwin_configuration">Configuration for Cygwin GCC from a
Windows prompt</a></h3>
The following settings may be useful when building with <a href=
"http://www.cygwin.com">Cygwin</a> GCC (not MinGW) from a Windows command
shell using a Windows build of <code>bjam</code>. <b>If
"<code>bjam&nbsp;-v</code>" does not report "<code>OS=NT</code>", these
settings do not apply to you</b>; you should use the <a href=
"#configuration">normal configuration</a> variables instead. They are
only useful when building and testing with multiple toolsets on Windows
using a single build command, since Cygwin GCC requires a different build
of Python.
<table border="1" summary=
"Cygwin GCC under NT build configuration variables">
<tr>
<th>Variable Name</th>
<th>Semantics</th>
<th>Default</th>
</tr>
<tr>
<td><code>CYGWIN_PYTHON_[DEBUG_]VERSION</code></td>
<td>The version of python being used under Cygwin.</td>
<td>$(PYTHON_VERSION)</td>
</tr>
<tr>
<td><code>CYGWIN_PYTHON_[DEBUG_]ROOT</code></td>
<td>unix-style path containing the <code>include/</code> directory
containing
<code>python$(CYGWIN_PYTHON_[DEBUG_]VERSION)/python.h</code>.</td>
<td>$(PYTHON_ROOT)</td>
</tr>
<tr>
<td><code>CYGWIN_PYTHON_[DEBUG_]LIB_PATH</code></td>
<td>path containing the user's Cygwin Python import lib
<code>libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll.a</code></td>
<td>Autoconfigured from <code>CYGWIN_PYTHON_ROOT</code></td>
</tr>
<tr>
<td><code>CYGWIN_PYTHON_[DEBUG_]DLL_PATH</code></td>
<td>path containing the user's Cygwin Python dll
(<code>libpython$(CYGWIN_PYTHON_[DEBUG_]VERSION).dll</code>)</td>
<td><code>/bin</code></td>
</tr>
</table>
<h3><a name="cygwin">Notes for Cygwin GCC Users</a></h3>
<p>If you are using Cygwin GCC to build extension modules, you must use a
Cygwin build of Python. The regular Win32 Python installation that you
can download from <a href="http://www.python.org">python.org</a> will not
work with your compiler because the dynamic linking conventions are
different (you can use <a href="http://www.mingw.org/">MinGW</a> GCC if
you want to build extension modules which are compatible with a stock
Win32 Python). The Cygwin installer may be able to install an appropriate
version of Python, or you can follow the traditional <a href=
"http://www.python.org/download/download_source.html">Unix installation
process</a> to build Python from source.</p>
<p>The special build configuration variables listed <a href=
"#cygwin_configuration">above</a> make it possible to use a regular Win32
build of bjam to build and test Boost.Python and Boost.Python extensions
using Cygwin GCC and targeting a Cygwin build of Python.</p>
<h3><a name="mingw">Notes for MinGW (and Cygwin with -mno-cygwin) GCC
Users</a></h3>
<p>You will need to create a MinGW-compatible version of the Python
library; the one shipped with Python will only work with a
Microsoft-compatible linker. Follow the instructions in the
"Non-Microsoft" section of the "Building Extensions: Tips And Tricks"
chapter in <a href=
"http://www.python.org/doc/current/inst/index.html">Installing Python
Modules</a> to create <code>libpythonXX.a</code>, where <code>XX</code>
corresponds to the major and minor version numbers of your Python
installation.</p>
<h3><a name="results">Results</a></h3>
<p>The build process will create a
@@ -183,7 +249,7 @@
<blockquote>
<pre>
bjam -sTOOLS=<i><a href=
"../../../tools/build/index.html#Tools">toolset</a></i> test
"../../../more/getting_started.html#Tools">toolset</a></i> test
</pre>
</blockquote>
This will update all of the Boost.Python v1 test and example targets. The
@@ -193,47 +259,62 @@ bjam -sTOOLS=<i><a href=
<blockquote>
<pre>
bjam -sTOOLS=<i><a href=
"../../../tools/build/index.html#Tools">toolset</a></i> -sPYTHON_TEST_ARGS=-v test
"../../../more/getting_started.html#Tools">toolset</a></i> -sPYTHON_TEST_ARGS=-v test
</pre>
</blockquote>
which will print each test's Python code with the expected output as it
passes.
<h2><a name="building_ext">Building your Extension Module</a></h2>
Though there are other approaches, the easiest way to build an extension
module using Boost.Python is with Boost.Build. Until Boost.Build v2 is
released, cross-project build dependencies are not supported, so it works
most smoothly if you add a new subproject to your boost installation. The
<code>libs/python/example</code> subdirectory of your boost installation
contains a minimal example (along with many extra sources). To copy the
example subproject:
Though there are other approaches, the smoothest and most reliable
way to build an extension module using Boost.Python is with
Boost.Build. If you have to use another build system, you should
use Boost.Build at least once with the
"<code><b>-n</b></code>" option so you can see the command-lines it uses,
and replicate them. You are likely to run into compilation or linking
problems otherwise.
<ol>
<li>Create a new subdirectory in, <code>libs/python</code>, say
<code>libs/python/my_project</code>.</li>
The <code><a href="../example">libs/python/example</a></code>
subdirectory of your boost installation contains a small example
which builds and tests two extensions. To build your own
extensions copy the example subproject and make the following two edits:
<li>Copy <code><a href=
"../example/Jamfile">libs/python/example/Jamfile</a></code> to your new
directory.</li>
<ol>
<li><code><a
href="../example/boost-build.jam"><b>boost-build.jam</b></a></code> -
edit the line which reads
<li>Edit the Jamfile as appropriate for your project. You'll want to
change the "<code>subproject</code>" rule invocation at the top, and
the names of some of the source files and/or targets.</li>
</ol>
If you can't modify or copy your boost installation, the alternative is
to create your own Boost.Build project. A similar example you can use as
a starting point is available in <code><a href=
"../example/project.zip">this archive</a></code>. You'll need to edit the
Jamfile and Jamrules files, depending on the relative location of your
Boost installation and the new project. Note that automatic testing of
extension modules is not available in this configuration.
<blockquote>
<pre>
boost-build ../../../tools/build/v1 ;
</pre>
</blockquote>
so that the path refers to the <code>tools/build/v1</code> subdirectory
of your Boost installation.
<li><code><a href="../example/Jamrules"><b>Jamrules</b></a></code> -
edit the line which reads
<blockquote>
<pre>
path-global BOOST_ROOT : ../../.. ;
</pre>
</blockquote>
so that the path refers to the root directory of your Boost installation.
</ol>
<p>
The instructions <a href="#testing">above</a> for testing Boost.Python
apply equally to your new extension modules in this subproject.
<h2><a name="variants">Build Variants</a></h2>
Three <a href=
"../../../tools/build/build_system.htm#variants">variant</a>
"../../../tools/build/v1/build_system.htm#variants">variant</a>
configurations of all python-related targets are supported, and can be
selected by setting the <code><a href=
"../../../tools/build/build_system.htm#user_globals">BUILD</a></code>
"../../../tools/build/v1/build_system.htm#user_globals">BUILD</a></code>
variable:
<ul>
@@ -280,6 +361,55 @@ bjam -sTOOLS=<i><a href=
instead of the usual <tt>Python.h</tt>, or you will have link
incompatibilities.<br>
</p>
<h2><a name="VisualStudio">Building Using the Microsoft Visual Studio
IDE</a></h2>
<p>For the those of you who feel more comfortable in the IDE world, a
workspace and project file have been included in the <a href=
"../build/VisualStudio">libs/python/build/VisualStudio</a> subdirectory.
It builds release and debug versions of the Boost.Python libraries and
places them and the same directory as Jamfile build does, though the
intermediate object files are placed in a different directory. The files
have been created using Microsoft Visual C++ version 6, but they should
work for later versions as well. You will need to tell the IDE where to
find the Python <code>Include/</code> and <code>Libs/</code> directories.
Under <b>Tools&gt;Options&gt;Directories</b>, add an entry for the Python
include dir (i.e. <code>c:/Python22/Include</code>), and one for the Lib
(i.e. <code>c:/Python/Libs</code>. Make sure it is <code>Libs</code> with
an "<code>s</code>" and not just <code>Lib</code>).</p>
<h3>Using the IDE for your own projects</h3>
<p>Building your own projects using the IDE is slightly more complicated.
Firstly, you need to make sure that the project you create as the right
kind. It should be a "Win32 Dynamic-Link Library". The default one that
Visual Studio 6 creates needs some modifications: turn on RTTI, and
change the debug and release builds to use the respective debug and
release Multithreaded DLL versions. You should probably turn off
incremental linking too -- I believe it a bit flaky. If you do this, then
change the "Debug Info" to "Program Database" to get rid of the Edit and
Continue warning.</p>
<p>You'll need to add the Boost root directory under
<b>Tools&gt;Options&gt;Directories</b> to get your code compiling. To
make it link, add the above <code>boost_python.dsp</code> file to your
workspace, and make your project depend upon it (under
<b>Project&gt;Dependencies</b>). You should be able to build now.</p>
<p>Lastly, go to the <b>Project Settings&gt;Debug</b> Page and add the
<code>Python.exe</code> as the executable for the project. Set a startup
directory, and make sure that your current project's output dll, the
<code>boost_python.dll</code> and the <code>python22.dll</code> are on
the current <code>PATH</code>. If you have a python script that tests
your dll, then add it in the "Program Arguments". Now, if all went well,
you should be able to hit the Run (F5) button, and debug your code.</p>
<blockquote>
<em>The Visual Studio project files are graciously contributed and
maintained by <a href="mailto:brett.calcott@paradise.net.nz">Brett
Calcott</a></em>.
</blockquote>
<hr>
<p>&copy; Copyright David Abrahams 2002. Permission to copy, use, modify,
@@ -288,7 +418,7 @@ bjam -sTOOLS=<i><a href=
express or implied warranty, and with no claim as to its suitability for
any purpose.</p>
<p>Updated: O8 October, 2002 (David Abrahams)</p>
<p>Updated: 29 December, 2002 (David Abrahams)</p>
</body>
</html>

View File

@@ -28,6 +28,42 @@
</table>
<hr>
<h2>Synopsis</h2>
Welcome to version 2 of <b>Boost.Python</b>, a C++ library which enables
seamless interoperability between C++ and the <a href=
"http://www.python.org">Python</a> programming language. The new version
has been rewritten from the ground up, with a more convenient and
flexible interface, and many new capabilities, including support for:
<ul>
<li>References and Pointers</li>
<li>Globally Registered Type Coercions</li>
<li>Automatic Cross-Module Type Conversions</li>
<li>Efficient Function Overloading</li>
<li>C++ to Python Exception Translation</li>
<li>Default Arguments</li>
<li>Keyword Arguments</li>
<li>Manipulating Python objects in C++</li>
<li>Exporting C++ Iterators as Python Iterators</li>
<li>Documentation Strings</li>
</ul>
The development of these features was funded in part by grants to <a
href="http://www.boost-consulting.com">Boost Consulting</a> from the <a
href="http://www.llnl.gov/">Lawrence Livermore National Laboratories</a>
and by the <a href="http://cci.lbl.gov/">Computational Crystallography
Initiative</a> at Lawrence Berkeley National Laboratories.
<hr>
<h2>Contents</h2>
<dl class="index">
@@ -35,30 +71,59 @@
<dt><a href="building.html">Building and Testing</a></dt>
<dt><a href="v2/reference.html">Reference</a></dt>
<dt><a href="v2/reference.html">Reference Manual</a></dt>
<dt>Suites:</dt>
<dd>
<ul>
<li><a href="v2/pickle.html">Pickle</a></li>
<li><a href="v2/indexing.html">Indexing</a></li>
</ul>
</dd>
<dt><a href="v2/configuration.html">Configuration Information</a></dt>
<dt><a href="v2/rationale.html">Rationale</a></dt>
<dt><a href="v2/platforms.html">Known Working Platforms and
Compilers</a></dt>
<dt><a href="v2/definitions.html">Definitions</a></dt>
<dt><a href="v2/faq.html">Frequently Asked Questions (FAQs)</a></dt>
<dt><a href="projects.html">Projects using Boost.Python</a></dt>
<dt><a href="v2/progress_reports.html">Progress Reports</a></dt>
<dt><a href="support.html">Support Resources</a></dt>
<dt><a href="v2/faq.html">Frequently Asked Questions (FAQs)</a></dt>
<dt><a href="../pyste/index.html">Pyste (Boost.Python code generator)</a></dt>
<dt><a href="internals.html">Internals Documentation</a></dt>
<dt><a href="news.html">News/Change Log</a></dt>
<dt><a href="../todo.html">TODO list</a></dt>
<dt><a href="v2/progress_reports.html">LLNL Progress Reports</a></dt>
<dt><a href="v2/acknowledgments.html">Acknowledgments</a></dt>
</dl>
<hr>
<p>Revised
<h2>Articles</h2>
&quot;<a href="PyConDC_2003/bpl.html">Building Hybrid
Systems With Boost Python</a>&quot;, by Dave Abrahams and Ralf
W. Grosse-Kunstleve (<a href="PyConDC_2003/bpl.pdf">PDF</a>)
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
08 October, 2002
26 August, 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i></p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002-2003. All Rights Reserved.</i></p>
</body>
</html>

186
doc/internals.html Executable file
View File

@@ -0,0 +1,186 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.3.0: http://docutils.sourceforge.net/" />
<title>Boost.Python Internals Boost</title>
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="boost-python-internals-logo">
<h1 class="title"><a class="reference" href="index.html">Boost.Python</a> Internals <a class="reference" href="../../../index.htm"><img alt="Boost" src="../../../c++boost.gif" /></a></h1>
<div class="section" id="a-conversation-between-brett-calcott-and-david-abrahams">
<h1><a name="a-conversation-between-brett-calcott-and-david-abrahams">A conversation between Brett Calcott and David Abrahams</a></h1>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">copyright:</th><td class="field-body">Copyright David Abrahams and Brett Calcott 2003. See
accompanying <a class="reference" href="../../../LICENSE_1_0.txt">license</a> for terms of use.</td>
</tr>
</tbody>
</table>
<p>In both of these cases, I'm quite capable of reading code - but the
thing I don't get from scanning the source is a sense of the
architecture, both structurally, and temporally (er, I mean in what
order things go on).</p>
<ol class="arabic">
<li><p class="first">What happens when you do the following:</p>
<pre class="literal-block">
struct boring {};
...etc...
class_&lt;boring&gt;(&quot;boring&quot;)
;
</pre>
</li>
</ol>
<p>There seems to be a fair bit going on.</p>
<blockquote>
<ul class="simple">
<li>Python needs a new ClassType to be registered.</li>
<li>We need to construct a new type that can hold our boring struct.</li>
<li>Inward and outward converters need to be registered for the type.</li>
</ul>
</blockquote>
<p>Can you gesture in the general direction where these things are done?</p>
<blockquote>
<p>I only have time for a &quot;off-the-top-of-my-head&quot; answer at the moment;
I suggest you step through the code with a debugger after reading this
to see how it works, fill in details, and make sure I didn't forget
anything.</p>
<blockquote>
<p>A new (Python) subclass of Boost.Python.Instance (see
libs/python/src/object/class.cpp) is created by invoking
Boost.Python.class, the metatype:</p>
<pre class="literal-block">
&gt;&gt;&gt; boring = Boost.Python.class(
... 'boring'
... , bases_tuple # in this case, just ()
... , {
... '__module__' : module_name
... , '__doc__' : doc_string # optional
... }
... )
</pre>
<p>A handle to this object is stuck in the m_class_object field
of the registration associated with <tt class="literal"><span class="pre">typeid(boring)</span></tt>. The
registry will keep that object alive forever, even if you
wipe out the 'boring' attribute of the extension module
(probably not a good thing).</p>
<p>Because you didn't specify <tt class="literal"><span class="pre">class&lt;boring,</span> <span class="pre">non_copyable,</span>
<span class="pre">...&gt;</span></tt>, a to-python converter for boring is registered which
copies its argument into a value_holder held by the the
Python boring object.</p>
<p>Because you didn't specify <tt class="literal"><span class="pre">class&lt;boring</span> <span class="pre">...&gt;(no_init)</span></tt>,
an <tt class="literal"><span class="pre">__init__</span></tt> function object is added to the class
dictionary which default-constructs a boring in a
value_holder (because you didn't specify some smart pointer
or derived wrapper class as a holder) held by the Python
boring object.</p>
<p><tt class="literal"><span class="pre">register_class_from_python</span></tt> is used to register a
from-python converter for <tt class="literal"><span class="pre">shared_ptr&lt;boring&gt;</span></tt>.
<tt class="literal"><span class="pre">boost::shared_ptr</span></tt>s are special among smart pointers
because their Deleter argument can be made to manage the
whole Python object, not just the C++ object it contains, no
matter how the C++ object is held.</p>
<p>If there were any <tt class="literal"><span class="pre">bases&lt;&gt;</span></tt>, we'd also be registering the
relationship between these base classes and boring in the
up/down cast graph (<tt class="literal"><span class="pre">inheritance.[hpp/cpp]</span></tt>).</p>
<p>In earlier versions of the code, we'd be registering lvalue
from-python converters for the class here, but now
from-python conversion for wrapped classes is handled as a
special case, before consulting the registry, if the source
Python object's metaclass is the Boost.Python metaclass.</p>
<p>Hmm, that from-python converter probably ought to be handled
the way class converters are, with no explicit conversions
registered.</p>
</blockquote>
</blockquote>
<ol class="arabic" start="2">
<li><p class="first">Can you give a brief overview of the data structures that are
present in the registry</p>
<blockquote>
<p>The registry is simple: it's just a map from typeid -&gt;
registration (see boost/python/converter/registrations.hpp).
<tt class="literal"><span class="pre">lvalue_chain</span></tt> and <tt class="literal"><span class="pre">rvalue_chain</span></tt> are simple endogenous
linked lists.</p>
<p>If you want to know more, just ask.</p>
<p>If you want to know about the cast graph, ask me something specific in
a separate message.</p>
</blockquote>
<p>and an overview of the process that happens as a type makes its
way from c++ to python and back again.</p>
</li>
</ol>
<blockquote>
<p>Big subject. I suggest some background reading: look for relevant
info in the LLNL progress reports and the messages they link to.
Also,</p>
<blockquote>
<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-May/001023.html">http://mail.python.org/pipermail/c++-sig/2002-May/001023.html</a></p>
<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-December/003115.html">http://mail.python.org/pipermail/c++-sig/2002-December/003115.html</a></p>
<p><a class="reference" href="http://aspn.activestate.com/ASPN/Mail/Message/1280898">http://aspn.activestate.com/ASPN/Mail/Message/1280898</a></p>
<p><a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-July/001755.html">http://mail.python.org/pipermail/c++-sig/2002-July/001755.html</a></p>
</blockquote>
<p>from c++ to python:</p>
<blockquote>
<p>It depends on the type and the call policies in use or, for
<tt class="literal"><span class="pre">call&lt;&gt;(...)</span></tt>, <tt class="literal"><span class="pre">call_method&lt;&gt;(...)</span></tt>, or <tt class="literal"><span class="pre">object(...)</span></tt>, if
<tt class="literal"><span class="pre">ref</span></tt> or <tt class="literal"><span class="pre">ptr</span></tt> is used. There are also two basic
categories to to-python conversion, &quot;return value&quot; conversion
(for Python-&gt;C++ calls) and &quot;argument&quot; conversion (for
C++-&gt;Python calls and explicit <tt class="literal"><span class="pre">object()</span></tt> conversions). The
behavior of these two categories differs subtly in various ways
whose details I forget at the moment. You can probably find
the answers in the above references, and certainly in the code.</p>
<p>The &quot;default&quot; case is by-value (copying) conversion, which uses
to_python_value as a to-python converter.</p>
<blockquote>
<p>Since there can sensibly be only one way to convert any type
to python (disregarding the idea of scoped registries for the
moment), it makes sense that to-python conversions can be
handled by specializing a template. If the type is one of
the types handled by a built-in conversion
(builtin_converters.hpp), the corresponding template
specialization of to_python_value gets used.</p>
<p>Otherwise, to_python_value uses the <tt class="literal"><span class="pre">m_to_python</span></tt>
function in the registration for the C++ type.</p>
</blockquote>
<p>Other conversions, like by-reference conversions, are only
available for wrapped classes, and are requested explicitly by
using <tt class="literal"><span class="pre">ref(...)</span></tt>, <tt class="literal"><span class="pre">ptr(...)</span></tt>, or by specifying different
CallPolicies for a call, which can cause a different to-python
converter to be used. These conversions are never registered
anywhere, though they do need to use the registration to find
the Python class corresponding to the C++ type being referred
to. They just build a new Python instance and stick the
appropriate Holder instance in it.</p>
</blockquote>
<p>from python to C++:</p>
<blockquote>
<p>Once again I think there is a distinction between &quot;return value&quot;
and &quot;argument&quot; conversions, and I forget exactly what that is.</p>
<p>What happens depends on whether an lvalue conversion is needed
(see <a class="reference" href="http://mail.python.org/pipermail/c++-sig/2002-May/001023.html">http://mail.python.org/pipermail/c++-sig/2002-May/001023.html</a>)
All lvalue conversions are also registered in a type's rvalue
conversion chain, since when an rvalue will do, an lvalue is
certainly good enough.</p>
<p>An lvalue conversion can be done in one step (just get me the
pointer to the object - it can be <tt class="literal"><span class="pre">NULL</span></tt> if no conversion is
possible) while an rvalue conversion requires two steps to
support wrapped function overloading and multiple converters for
a given C++ target type: first tell me if a conversion is
possible, then construct the converted object as a second step.</p>
</blockquote>
</blockquote>
</div>
</div>
<hr class="footer"/>
<div class="footer">
<a class="reference" href="internals.rst">View document source</a>.
Generated on: 2003-09-12 14:51 UTC.
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

182
doc/internals.rst Executable file
View File

@@ -0,0 +1,182 @@
===================================
Boost.Python_ Internals |(logo)|__
===================================
.. |(logo)| image:: ../../../c++boost.gif
:alt: Boost
:class: boost-logo
__ ../../../index.htm
.. _`Boost.Python`: index.html
.. _license: ../../../LICENSE_1_0.txt
-------------------------------------------------------
A conversation between Brett Calcott and David Abrahams
-------------------------------------------------------
:copyright: Copyright David Abrahams and Brett Calcott 2003. See
accompanying license_ for terms of use.
In both of these cases, I'm quite capable of reading code - but the
thing I don't get from scanning the source is a sense of the
architecture, both structurally, and temporally (er, I mean in what
order things go on).
1) What happens when you do the following::
struct boring {};
...etc...
class_<boring>("boring")
;
There seems to be a fair bit going on.
- Python needs a new ClassType to be registered.
- We need to construct a new type that can hold our boring struct.
- Inward and outward converters need to be registered for the type.
Can you gesture in the general direction where these things are done?
I only have time for a "off-the-top-of-my-head" answer at the moment;
I suggest you step through the code with a debugger after reading this
to see how it works, fill in details, and make sure I didn't forget
anything.
A new (Python) subclass of Boost.Python.Instance (see
libs/python/src/object/class.cpp) is created by invoking
Boost.Python.class, the metatype::
>>> boring = Boost.Python.class(
... 'boring'
... , bases_tuple # in this case, just ()
... , {
... '__module__' : module_name
... , '__doc__' : doc_string # optional
... }
... )
A handle to this object is stuck in the m_class_object field
of the registration associated with ``typeid(boring)``. The
registry will keep that object alive forever, even if you
wipe out the 'boring' attribute of the extension module
(probably not a good thing).
Because you didn't specify ``class<boring, non_copyable,
...>``, a to-python converter for boring is registered which
copies its argument into a value_holder held by the the
Python boring object.
Because you didn't specify ``class<boring ...>(no_init)``,
an ``__init__`` function object is added to the class
dictionary which default-constructs a boring in a
value_holder (because you didn't specify some smart pointer
or derived wrapper class as a holder) held by the Python
boring object.
``register_class_from_python`` is used to register a
from-python converter for ``shared_ptr<boring>``.
``boost::shared_ptr``\ s are special among smart pointers
because their Deleter argument can be made to manage the
whole Python object, not just the C++ object it contains, no
matter how the C++ object is held.
If there were any ``bases<>``, we'd also be registering the
relationship between these base classes and boring in the
up/down cast graph (``inheritance.[hpp/cpp]``).
In earlier versions of the code, we'd be registering lvalue
from-python converters for the class here, but now
from-python conversion for wrapped classes is handled as a
special case, before consulting the registry, if the source
Python object's metaclass is the Boost.Python metaclass.
Hmm, that from-python converter probably ought to be handled
the way class converters are, with no explicit conversions
registered.
2) Can you give a brief overview of the data structures that are
present in the registry
The registry is simple: it's just a map from typeid ->
registration (see boost/python/converter/registrations.hpp).
``lvalue_chain`` and ``rvalue_chain`` are simple endogenous
linked lists.
If you want to know more, just ask.
If you want to know about the cast graph, ask me something specific in
a separate message.
and an overview of the process that happens as a type makes its
way from c++ to python and back again.
Big subject. I suggest some background reading: look for relevant
info in the LLNL progress reports and the messages they link to.
Also,
http://mail.python.org/pipermail/c++-sig/2002-May/001023.html
http://mail.python.org/pipermail/c++-sig/2002-December/003115.html
http://aspn.activestate.com/ASPN/Mail/Message/1280898
http://mail.python.org/pipermail/c++-sig/2002-July/001755.html
from c++ to python:
It depends on the type and the call policies in use or, for
``call<>(...)``, ``call_method<>(...)``, or ``object(...)``, if
``ref`` or ``ptr`` is used. There are also two basic
categories to to-python conversion, "return value" conversion
(for Python->C++ calls) and "argument" conversion (for
C++->Python calls and explicit ``object()`` conversions). The
behavior of these two categories differs subtly in various ways
whose details I forget at the moment. You can probably find
the answers in the above references, and certainly in the code.
The "default" case is by-value (copying) conversion, which uses
to_python_value as a to-python converter.
Since there can sensibly be only one way to convert any type
to python (disregarding the idea of scoped registries for the
moment), it makes sense that to-python conversions can be
handled by specializing a template. If the type is one of
the types handled by a built-in conversion
(builtin_converters.hpp), the corresponding template
specialization of to_python_value gets used.
Otherwise, to_python_value uses the ``m_to_python``
function in the registration for the C++ type.
Other conversions, like by-reference conversions, are only
available for wrapped classes, and are requested explicitly by
using ``ref(...)``, ``ptr(...)``, or by specifying different
CallPolicies for a call, which can cause a different to-python
converter to be used. These conversions are never registered
anywhere, though they do need to use the registration to find
the Python class corresponding to the C++ type being referred
to. They just build a new Python instance and stick the
appropriate Holder instance in it.
from python to C++:
Once again I think there is a distinction between "return value"
and "argument" conversions, and I forget exactly what that is.
What happens depends on whether an lvalue conversion is needed
(see http://mail.python.org/pipermail/c++-sig/2002-May/001023.html)
All lvalue conversions are also registered in a type's rvalue
conversion chain, since when an rvalue will do, an lvalue is
certainly good enough.
An lvalue conversion can be done in one step (just get me the
pointer to the object - it can be ``NULL`` if no conversion is
possible) while an rvalue conversion requires two steps to
support wrapped function overloading and multiple converters for
a given C++ target type: first tell me if a conversion is
possible, then construct the converted object as a second step.

View File

@@ -318,7 +318,9 @@ until the result object is retrieved.</font>
Special Edition Addison-Wesley, ISBN 0-201-70073-5.
<hr>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->19 December 2001<!--webbot bot="Timestamp" endspan i-checksum="31283" --></p>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="31283" --></p>
<p>© Copyright David Abrahams, 2001</p>
</body>

191
doc/news.html Normal file
View File

@@ -0,0 +1,191 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="boost.css">
<title>Boost.Python - News/Change Log</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="index.html">Boost.Python</a></h1>
<h2 align="center">News/Change Log</h2>
</td>
</tr>
</table>
<hr>
<dl class="page-index">
<dt>11 Sept 2003</dt>
<dd>
<ul>
<li>Changed the response to multiple to-python converters being
registered for the same type from a hard error into warning;
Boost.Python now reports the offending type in the message.</li>
<li>Added builtin <code>std::wstring</code> conversions</li>
<li>Added <code>std::out_of_range</code> =&gt; Python
<code>IndexError</code> exception conversion, thanks to <a href=
"mailto:RaoulGough-at-yahoo.co.uk">Raoul Gough</a></li>
</ul>
</dd>
<dt>9 Sept 2003</dt>
<dd>Added new <code><a href="v2/str.html#str-spec">str</a></code></dd>
<dt>constructors which take a range of characters, allowing strings
containing nul (<code>'\0'</code>) characters.</dt>
<dt>8 Sept 2003</dt>
<dd>Added the ability to create methods from function objects (with an
<code>operator()</code>); see the <a href=
"v2/make_function.html#make_function-spec">make_function</a> docs for
more info.</dd>
<dt>10 August 2003</dt>
<dd>Added the new <code>properties</code> unit tests contributed by <a
href="mailto:romany-at-actimize.com">Roman Yakovenko</a> and documented
<code>add_static_property</code> at his urging.</dd>
<dt>1 August 2003</dt>
<dd>
Added the new <code>arg</code> class contributed by <a href=
"mailto:nickm-at-sitius.com">Nikolay Mladenov</a> which supplies the
ability to wrap functions that can be called with ommitted arguments
in the middle:
<pre>
void f(int x = 0, double y = 3.14, std::string z = std::string("foo"));
BOOST_PYTHON_MODULE(test)
{
def("f", f
, (arg("x", 0), arg("y", 3.14), arg("z", "foo")));
}
</pre>
And in Python:
<pre>
&gt;&gt;&gt; import test
&gt;&gt;&gt; f(0, z = "bar")
&gt;&gt;&gt; f(z = "bar", y = 0.0)
</pre>
Thanks, Nikolay!
</dd>
<dt>22 July 2003</dt>
<dd>Killed the dreaded "bad argument type for builtin operation" error.
Argument errors now show the actual and expected argument types!</dd>
<dt>19 July 2003</dt>
<dd>Added the new <code><a href=
"v2/return_arg.html">return_arg</a></code> policy from <a href=
"mailto:nickm-at-sitius.com">Nikolay Mladenov</a>. Thanks,
Nikolay!</dd>
<dt>18 March, 2003</dt>
<dd><a href="mailto:Gottfried.Ganssauge-at-haufe.de">Gottfried
Gan&szlig;auge</a> has contributed <a href=
"v2/opaque_pointer_converter.html">opaque pointer support</a>.<br>
<a href="mailto:nicodemus-at-globalite.com.br">Bruno da Silva de Oliveira</a>
has contributed the exciting <a href="../pyste/index.html">Pyste</a>
("Pie-steh") package.</dd>
<dt>24 February 2003</dt>
<dd>Finished improved support for <code>boost::shared_ptr</code>. Now
any wrapped object of C++ class <code>X</code> can be converted
automatically to <code>shared_ptr&lt;X&gt;</code>, regardless of how it
was wrapped. The <code>shared_ptr</code> will manage the lifetime of
the Python object which supplied the <code>X</code>, rather than just
the <code>X</code> object itself, and when such a
<code>shared_ptr</code> is converted back to Python, the original
Python object will be returned.</dd>
<dt>19 January 2003</dt>
<dd>Integrated <code>staticmethod</code> support from <a href=
"mailto:nickm-at-sitius.com">Nikolay Mladenov</a>. Thanks,
Nikolay!</dd>
<dt>29 December 2002</dt>
<dd>Added Visual Studio project file and instructions from Brett
Calcott. Thanks, Brett!</dd>
<dt>20 December 2002</dt>
<dd>Added automatic downcasting for pointers, references, and smart
pointers to polymorphic class types upon conversion to python</dd>
<dt>18 December 2002</dt>
<dd>Optimized from_python conversions for wrapped classes by putting
the conversion logic in the shared library instead of registering
separate converters for each class in each extension module</dd>
<dt>19 November 2002</dt>
<dd>Removed the need for users to cast base class member function
pointers when used as arguments to <a href=
"v2/class.html#class_-spec-modifiers">add_property</a></dd>
<dt>13 December 2002</dt>
<dd>Allow exporting of <a href=
"v2/enum.html#enum_-spec"><code>enum_</code></a> values into enclosing
<a href="v2/scope.html#scope-spec"><code>scope</code></a>.<br>
Fixed unsigned integer conversions to deal correctly with numbers that
are out-of-range of <code>signed long</code>.</dd>
<dt>14 November 2002</dt>
<dd>Auto-detection of class data members wrapped with <a href=
"v2/data_members.html#make_getter-spec"><code>make_getter</code></a></dd>
<dt>13 November 2002</dt>
<dd>Full Support for <code>std::auto_ptr&lt;&gt;</code> added.</dd>
<dt>October 2002</dt>
<dd>Ongoing updates and improvements to tutorial documentation</dd>
<dt>10 October 2002</dt>
<dd>Boost.Python V2 is released!</dd>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
11 September 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002-2003. All Rights Reserved.</i></p>
</body>
</html>

217
doc/polymorphism.txt Normal file
View File

@@ -0,0 +1,217 @@
How Runtime Polymorphism is expressed in Boost.Python:
-----------------------------------------------------
struct A { virtual std::string f(); virtual ~A(); };
std::string call_f(A& x) { return x.f(); }
struct B { virtual std::string f() { return "B"; } };
struct Bcb : B
{
Bcb(PyObject* self) : m_self(self) {}
virtual std::string f() { return call_method<std::string>(m_sef, "f"); }
static std::string f_default(B& b) { return b.B::f(); }
PyObject* m_self;
};
struct C : B
{
virtual std::string f() { return "C"; }
};
>>> class D(B):
... def f():
... return 'D'
...
>>> class E(B): pass
...
When we write, "invokes B::f non-virtually", we mean:
void g(B& x) { x.B::f(); }
This will call B::f() regardless of the dynamic type of x. Any other
way of invoking B::f, including through a function pointer, is a
"virtual invocation", and will call the most-derived override of f().
Case studies
C++\Python class
\___A_____B_____C_____D____E___
|
A | 1
|
B | 2 3
|
Bcb | 4 5 6
|
C | 7 8
|
1. Simple case
2. Python A holds a B*. Probably won't happen once we have forced
downcasting.
Requires:
x.f() -> 'B'
call_f(x) -> 'B'
Implies: A.f invokes A::f() (virtually or otherwise)
3. Python B holds a B*.
Requires:
x.f() -> 'B'
call_f(x) -> 'B'
Implies: B.f invokes B::f (virtually or otherwise)
4. B constructed from Python
Requires:
x.f() -> 'B'
call_f(x) -> 'B'
Implies: B.f invokes B::f non-virtually. Bcb::f invokes B::f
non-virtually.
Question: Does it help if we arrange for Python B construction to
build a true B object? Then this case doesn't arise.
5. D is a Python class derived from B
Requires:
x.f() -> 'D'
call_f(x) -> 'D'
Implies: Bcb::f must invoke call_method to look up the Python
method override, otherwise call_f wouldn't work.
6. E is like D, but doesn't override f
Requires:
x.f() -> 'B'
call_f(x) -> 'B'
Implies: B.f invokes B::f non-virtually. If it were virtual, x.f()
would cause infinite recursion, because we've already
determined that Bcb::f must invoke call_method to look up
the Python method override.
7. Python B object holds a C*
Requires:
x.f() -> 'C'
call_f(x) -> 'C'
Implies: B.f invokes B::f virtually.
8. C object constructed from Python
Requires:
x.f() -> 'C'
call_f(x) -> 'C'
Implies: nothing new.
------
Total implications:
2: A.f invokes A::f() (virtually or otherwise)
3: B.f invokes B::f (virtually or otherwise)
4: B.f invokes B::f non-virtually. Bcb::f invokes B::f non-virtually
6: B.f invokes B::f non-virtually.
7: B.f invokes B::f virtually.
5: Bcb::f invokes call_method to look up the Python method
Though (4) is avoidable, clearly 6 and 7 are not, and they
conflict. The implication is that B.f must choose its behavior
according to the type of the contained C++ object. If it is Bcb, a
non-virtual call to B::f must occur. Otherwise, a virtual call to B::f
must occur. This is essentially the same scheme we had with
Boost.Python v1.
Note: in early versions of Boost.Python v1, we solved this problem by
introducing a new Python class in the hierarchy, so that D and E
actually derive from a B', and B'.f invokes B::f non-virtually, while
B.f invokes B::f virtually. However, people complained about the
artificial class in the hierarchy, which was revealed when they tried
to do normal kinds of Python introspection.
-------
Assumption: we will have a function which builds a virtual function
dispatch callable Python object.
make_virtual_function(pvmf, default_impl, call_policies, dispatch_type)
Pseudocode:
Get first argument from Python arg tuple
if it contains dispatch_type
call default_impl
else
call through pvmf
Open questions:
1. What about Python multiple inheritance? Do we have the right
check in the if clause above?
A: Not quite. The correct test looks like:
Deduce target type of pvmf, i.e. T in R(T::*)(A1...AN).
Find holder in first argument which holds T
if it holds dispatch_type...
2. Can we make this more efficient?
The current "returning" mechanism will look up a holder for T
again. I don't know if we know how to avoid that.
OK, the solution involves reworking the call mechanism. This is
neccesary anyway in order to enable wrapping of function objects.
It can result in a reduction in the overall amount of source code,
because returning<> won't need to be specialized for every
combination of function and member function... though it will still
need a void specialization. We will still need a way to dispatch to
member functions through a regular function interface. mem_fn is
almost the right tool, but it only goes up to 8
arguments. Forwarding is tricky if you don't want to incur copies.
I think the trick is to use arg_from_python<T>::result_type for each
argument to the forwarder.
Another option would be to use separate function, function object,
and member function dispatchers. Once you know you have a member
function, you don't need cv-qualified overloads to call it.
Hmm, while we're at this, maybe we should solve the write-back
converter problem. Can we do it? Maybe not. Ralf doesn't want to
write special write-back functions here, does he? He wants the
converter to do the work automatically. We could add
cleanup/destructor registration. That would relieve the client from
having accessible destructors for types which are being converted by
rvalue. I'm not sure that this will really save any code,
however. It rather depends on the linker, doesn't it? I wonder if
this can be done in a backwards-compatible fashion by generating the
delete function when it's not supplied?

344
doc/projects.html Normal file
View File

@@ -0,0 +1,344 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="boost.css">
<title>Boost.Python - Projects using Boost.Python</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="index.html">Boost.Python</a></h1>
<h2 align="center">Projects using Boost.Python</h2>
</td>
</tr>
</table>
<hr>
<h2>Introduction</h2>
<p>This is a partial list of projects using Boost.Python. If you are
using Boost.Python as your Python/C++ binding solution, we'd be proud to
list your project on this page. Just <a href=
"mailto:c++-sig@python.org">post</a> a short description of your project
and how Boost.Python helps you get the job done, and we'll add it to this
page .</p>
<hr>
<h3>Data Analysis</h3>
<dl class="page-index">
<dt><b><a href=
"http://www.neuralynx.com/neuralab/index.htm">NeuraLab</a></b></dt>
<dd>Neuralab is a data analysis environment specifically tailored for
neural data from <a href="http://www.neuralynx.com">Neuralynx</a>
acquisition systems. Neuralab combines presentation quality graphics, a
numerical analysis library, and the <a href=
"http://www.python.org">Python</a> scripting engine in a single
application. With Neuralab, Neuralynx users can perform common analysis
tasks with just a few mouse clicks. More advanced users can create
custom Python scripts, which can optionally be assigned to menus and
mouse clicks.</dd>
</dl>
<dl class="page-index">
<dt><b>TSLib</b> - <a href="http://www.fortressinv.com">Fortress
Investment Group LLC</a></dt>
<dd>
Fortress Investment Group has contracted <a href=
"http://www.boost-consulting.com">Boost Consulting</a> to develop
core internal financial analysis tools in C++ and to prepare Python
bindings for them using Boost.Python.
<p>Tom Barket of Fortress writes:</p>
<blockquote>
We have a large C++ analytical library specialized for research in
finance and economics, built for speed and mission critical
stability. Yet Python offers us the flexibility to test out new
ideas quickly and increase the productivity of our time versus
working in C++. There are several key features which make Python
stand out. Its elegance, stability, and breadth of resources on the
web are all valuable, but the most important is its extensibility,
due to its open source transparency. Boost.Python makes Python
extensibility extremely simple and straightforward, yet preserves a
great deal of power and control.
</blockquote>
</dd>
</dl>
<h3>Educational</h3>
<dl class="page-index">
<dt><a href="http://edu.kde.org/kig"><b>Kig</b></a></dt>
<dd>
<p>KDE Interactive Geometry is a high-school level educational tool,
built for the KDE desktop. It is a nice tool to let students work
with geometrical constructions. It is meant to be the most intuitive,
yet featureful application of its kind.</p>
<p>Versions after 0.6.x (will) support objects built by the user
himself in the Python language. The exporting of the relevant
internal API's were done using Boost.Python, which made the process
very easy.</p>
</dd>
</dl>
<h3>Enterprise Software</h3>
<dl class="page-index">
<dt><b><a href="http://openwbem.sourceforge.net">OpenWBEM</a></b></dt>
<dd>
The OpenWBEM project is an effort to develop an open-source
implementation of Web Based Enterprise Management suitable for
commercial and non-commercial application
<p><a href="mailto:dnuffer@sco.com">Dan Nuffer</a> writes:</p>
<blockquote>
I'm using Boost.Python to wrap the client API of OpenWBEM.This will
make it easier to do rapid prototyping, testing, and scripting when
developing management solutions that use WBEM.
</blockquote>
</dd>
<dt><b><a href="http://www.transversal.com">Metafaq</a></b></dt>
<dd>
Metafaq, from <a href="http://www.transversal.com">Transversal,
Inc.</a>, is an enterprise level online knowledge base management
system.
<p><a href="mailto:ben.young-at-transversal.com">Ben Young</a>
writes:</p>
<blockquote>
Boost.Python is used in an automated process to generate python
bindings to our api which is exposed though multiple backends and
frontends. This allows us to write quick tests and bespoke scripts
to perform one off tasks without having to go through the full
compilation cycle.
</blockquote>
</dd>
</dl>
<h3>Graphics</h3>
<dl class="page-index">
<dt><b><a href="http://sourceforge.net/projects/pyosg">OpenSceneGraph
Bindings</a></b></dt>
<dd><a href="mailto:gideon@computer.org">Gideon May</a> has created a
set of bindings for <a href=
"http://www.openscenegraph.org">OpenSceneGraph</a>, a cross-platform
C++/OpenGL library for the real-time visualization.<br>
&nbsp;</dd>
<dt><a href=
"http://www.procoders.net/pythonmagick"><b>PythonMagick</b></a></dt>
<dd>PythonMagick binds the <a href=
"http://www.graphicsmagick.org">GraphicsMagick</a> image manipulation
library to Python.<br>
&nbsp;</dd>
<dt><b><a href=
"http://www.slac.stanford.edu/grp/ek/hippodraw/index.html">HippoDraw</a></b></dt>
<dd>
HippoDraw is a data analysis environment consisting of a canvas upon
which graphs such as histograms, scattter plots, etc, are prsented.
It has a highly interactive GUI interface, but some things you need
to do with scripts. HippoDraw can be run as Python extension module
so that all the manipulation can be done from either Python or the
GUI.
<p>Before the web page came online, <a href=
"mailto:Paul_Kunz@SLAC.Stanford.EDU">Paul F. Kunz</a> wrote:</p>
<blockquote>
Don't have a web page for the project, but the organization's is <a
href=
"http://www.slac.stanford.edu">http://www.slac.stanford.edu</a>
(the first web server site in America, I installed it).
</blockquote>
Which was just too cool a piece of trivia to omit.<br>
&nbsp;
</dd>
</dl>
<h3>Scientific Computing</h3>
<dl class="page index">
<dt><a href="http://camfr.sourceforge.net"><b>CAMFR</b></a></dt>
<dd>
CAMFR is a photonics and electromagnetics modelling tool. Python is
used for computational steering.
<p><a href="mailto:Peter.Bienstman@rug.ac.be">Peter Bienstman</a>
writes:</p>
<blockquote>
Thanks for providing such a great tool!
</blockquote>
</dd>
<dt><a href="http://cctbx.sourceforge.net"><b>cctbx - Computational
Crystallography Toolbox</b></a></dt>
<dd>
Computational Crystallography is concerned with the derivation of
atomic models of crystal structures, given experimental X-ray
diffraction data. The cctbx is an open-source library of fundamental
algorithms for crystallographic computations. The core algorithms are
implemented in C++ and accessed through higher-level Python
interfaces.
<p>The cctbx grew together with Boost.Python and is designed from the
ground up as a hybrid Python/C++ system. With one minor exception,
run-time polymorphism is completely handled by Python. C++
compile-time polymorphism is used to implement performance critical
algorithms. The Python and C++ layers are seamlessly integrated using
Boost.Python.</p>
<p>The SourceForge cctbx project is organized in modules to
facilitate use in non-crystallographic applications. The scitbx
module implements a general purpose array family for scientific
applications and pure C++ ports of FFTPACK and the LBFGS conjugate
gradient minimizer.</p>
</dd>
<dt><a href="http://www.llnl.gov/CASC/emsolve"><b>EMSolve</b></a></dt>
<dd>EMSolve is a provably stable, charge conserving, and energy
conserving solver for Maxwell's equations.<br>
&nbsp;</dd>
<dt><b><a href="http://cern.ch/gaudi">Gaudi</a></b> and <b><a href=
"http://cern.ch/Gaudi/RootPython/">RootPython</a></b></dt>
<dd>
Gaudi is a framework for particle physics collision data processing
applications developed in the context of the LHCb and ATLAS
experiments at CERN.
<p><a href="mailto:Pere.Mato@cern.ch">Pere Mato Vila</a> writes:</p>
<blockquote>
We are using Boost.Python to provide scripting/interactive
capability to our framework. We have a module called "GaudiPython"
implemented using Boost.Python that allows the interaction with any
framework service or algorithm from python. RootPython also uses
Boost.Python to provide a generic "gateway" between the <a href=
"http://root.cern.ch">ROOT</a> framework and python
<p>Boost.Python is great. We managed very quickly to interface our
framework to python, which is great language. We are trying to
facilitate to our physicists (end-users) a rapid analysis
application development environment based on python. For that,
Boost.Python plays and essential role.</p>
</blockquote>
</dd>
<dt><b><a href="http://www.esss.com.br">ESSS</a></b></dt>
<dd>
ESSS (Engineering Simulation and Scientific Software) is a company
that provides engineering solutions and acts in the brazilian and
south-american market providing products and services related to
Computational Fluid Dynamics and Image Analysis.
<p><a href="mailto:bruno@esss.com.br">Bruno da Silva de Oliveira</a>
writes:</p>
<blockquote>
Recently we moved our work from working exclusively with C++ to an
hybrid-language approach, using Python and C++, with Boost.Python
providing the layer between the two. The results are great so far!
</blockquote>
<p>Two projects have been developed so far with this technology:</p>
<p><b><a href="http://www.esss.com.br/dev_simba.phtml">Simba</a></b>
provides 3D visualization of geological formations gattered from the
simulation of the evolution of oil systems, allowing the user to
analyse various aspects of the simulation, like deformation, pressure
and fluids, along the time of the simulation.</p>
<p><b><a href="http://www.esss.com.br/dev_aero.phtml">Aero</a></b>
aims to construct a CFD with brazilian technology, which involves
various companies and universities. ESSS is responsible for various
of the application modules, including GUI and post-processing of
results.</p>
</dd>
<dt><b><a href="http://www.rationaldiscovery.com">Rational Discovery
LLC</a></b></dt>
<dd>
Rational Discovery provides computational modeling, combinatorial
library design and custom software development services to the
pharmaceutical, biotech and chemical industries. We do a substantial
amount of internal research to develop new approaches for applying
machine-learning techniques to solve chemical problems. Because we're
a small organization and chemistry is a large and complex field, it
is essential that we be able to quickly and easily prototype and test
new algorithms.
<p>For our internal software, we implement core data structures in C
and expose them to Python using Boost.Python. Algorithm development
is done in Python and then translated to C if required (often it's
not). This hybrid development approach not only greatly increases our
productivity, but it also allows "non-developers" (people without C
experience) to take part in method development. Learning C is a
daunting task, but "Python fits your brain." (Thanks to Bruce Eckel
for the quote.)</p>
</dd>
</dl>
<h3>Tools</h3>
<dl>
<dt><a href="http://www.jayacard.org"><b>Jayacard</b></a></dt>
<dd>
Jayacard aims at developing a secure portable open source operating
system for contactless smart cards and a complete suite of high
quality development tools to ease smart card OS and application
development.
<p>The core of the smart card reader management is written in C++ but
all the development tools are written in the friendly Python
language. Boost plays the fundamental role of binding the tools to
our core smart card reader library.</p>
</dd>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
15 July, 2003</p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002-2003. All Rights Reserved.</i></p>
</body>
</html>

71
doc/support.html Normal file
View File

@@ -0,0 +1,71 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="boost.css">
<title>Boost.Python - Support Resources</title>
</head>
<body link="#0000ff" vlink="#800080">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center"><a href="index.html">Boost.Python</a></h1>
<h2 align="center">Support Resources</h2>
</td>
</tr>
</table>
<hr>
<h2>Synopsis</h2>
<p>This is a list of available resources for support with Boost.Python
problems and feature requests. <b>Please try to resist emailing the
Boost.Python developers directly for support.</b> Use the following
resources instead; the developers are listening!</p>
<hr>
<dl class="page-index">
<dt><b><a href="http://www.boost-consulting.com">Boost
Consulting</a></b> - Commercial support, development, training, and
distribution for all the Boost libraries, from the people who brought
you Boost.Python.<br>
&nbsp;</dt>
<dt><b><a href=
"http://www.boost.org/more/mailing_lists.htm#cplussig">The Python
C++-sig</a></b> mailing list is a forum for discussing Python/C++
interoperability, and Boost.Python in particular. Post your
Boost.Python questions here.<br>
&nbsp;</dt>
<dt>The <b>Boost.Python <a href=
"http://www.python.org/cgi-bin/moinmoin/boost_2epython">Wiki
Pages</a></b> established by Mike Rovner as part of the <a href=
"http://www.python.org/cgi-bin/moinmoin">PythonInfo Wiki</a> serves as
a forum to gather peoples' experience and as a cookbook.<br>
&nbsp;</dt>
</dl>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
12 Sept, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2003.</i></p>
</body>
</html>

View File

@@ -0,0 +1,112 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Auto-Overloading</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="default_arguments.html">
<link rel="next" href="object_interface.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Auto-Overloading</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="default_arguments.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="object_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
It was mentioned in passing in the previous section that
<tt>BOOST_PYTHON_FUNCTION_OVERLOADS</tt> and <tt>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
can also be used for overloaded functions and member functions with a
common sequence of initial arguments. Here is an example:</p>
<code><pre>
<span class=keyword>void </span><span class=identifier>foo</span><span class=special>()
{
/*...*/
}
</span><span class=keyword>void </span><span class=identifier>foo</span><span class=special>(</span><span class=keyword>bool </span><span class=identifier>a</span><span class=special>)
{
/*...*/
}
</span><span class=keyword>void </span><span class=identifier>foo</span><span class=special>(</span><span class=keyword>bool </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>int </span><span class=identifier>b</span><span class=special>)
{
/*...*/
}
</span><span class=keyword>void </span><span class=identifier>foo</span><span class=special>(</span><span class=keyword>bool </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>int </span><span class=identifier>b</span><span class=special>, </span><span class=keyword>char </span><span class=identifier>c</span><span class=special>)
{
/*...*/
}
</span></pre></code>
<p>
Like in the previous section, we can generate thin wrappers for these
overloaded functions in one-shot:</p>
<code><pre>
<span class=identifier>BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class=special>(</span><span class=identifier>foo_overloads</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=number>0</span><span class=special>, </span><span class=number>3</span><span class=special>)
</span></pre></code>
<p>
Then...</p>
<code><pre>
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;foo&quot;</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=identifier>foo_overloads</span><span class=special>());
</span></pre></code>
<p>
Notice though that we have a situation now where we have a minimum of zero
(0) arguments and a maximum of 3 arguments.</p>
<a name="manual_wrapping"></a><h2>Manual Wrapping</h2><p>
It is important to emphasize however that <b>the overloaded functions must
have a common sequence of initial arguments</b>. Otherwise, our scheme above
will not work. If this is not the case, we have to wrap our functions
<a href="overloading.html">
manually</a>.</p>
<p>
Actually, we can mix and match manual wrapping of overloaded functions and
automatic wrapping through <tt>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt> and
its sister, <tt>BOOST_PYTHON_FUNCTION_OVERLOADS</tt>. Following up on our example
presented in the section <a href="overloading.html">
on overloading</a>, since the
first 4 overload functins have a common sequence of initial arguments, we
can use <tt>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt> to automatically wrap the
first three of the <tt>def</tt>s and manually wrap just the last. Here's
how we'll do this:</p>
<code><pre>
<span class=identifier>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class=special>(</span><span class=identifier>xf_overloads</span><span class=special>, </span><span class=identifier>f</span><span class=special>, </span><span class=number>1</span><span class=special>, </span><span class=number>4</span><span class=special>)
</span></pre></code>
<p>
Create a member function pointers as above for both X::f overloads:</p>
<code><pre>
<span class=keyword>bool </span><span class=special>(</span><span class=identifier>X</span><span class=special>::*</span><span class=identifier>fx1</span><span class=special>)(</span><span class=keyword>int</span><span class=special>, </span><span class=keyword>double</span><span class=special>, </span><span class=keyword>char</span><span class=special>) = &amp;</span><span class=identifier>X</span><span class=special>::</span><span class=identifier>f</span><span class=special>;
</span><span class=keyword>int </span><span class=special>(</span><span class=identifier>X</span><span class=special>::*</span><span class=identifier>fx2</span><span class=special>)(</span><span class=keyword>int</span><span class=special>, </span><span class=keyword>int</span><span class=special>, </span><span class=keyword>int</span><span class=special>) = &amp;</span><span class=identifier>X</span><span class=special>::</span><span class=identifier>f</span><span class=special>;
</span></pre></code>
<p>
Then...</p>
<code><pre>
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>fx1</span><span class=special>, </span><span class=identifier>xf_overloads</span><span class=special>());
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>fx2</span><span class=special>)
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="default_arguments.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="object_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -34,7 +34,7 @@ To illustrate, this Python code snippet:</p>
<code><pre>
<span class=identifier>def </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>x</span><span class=special>, </span><span class=identifier>y</span><span class=special>):
</span><span class=keyword>if </span><span class=special>(</span><span class=identifier>y </span><span class=special>== </span><span class=literal>'foo'</span><span class=special>):
</span><span class=identifier>x</span><span class=special>[</span><span class=number>3</span><span class=special>:</span><span class=number>7</span><span class=special>] </span><span class=special>= </span><span class=literal>'bar'
</span><span class=identifier>x</span><span class=special>[</span><span class=number>3</span><span class=special>:</span><span class=number>7</span><span class=special>] = </span><span class=literal>'bar'
</span><span class=keyword>else</span><span class=special>:
</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>items </span><span class=special>+= </span><span class=identifier>y</span><span class=special>(</span><span class=number>3</span><span class=special>, </span><span class=identifier>x</span><span class=special>)
</span><span class=keyword>return </span><span class=identifier>x
@@ -45,16 +45,16 @@ To illustrate, this Python code snippet:</p>
<p>
Can be rewritten in C++ using Boost.Python facilities this way:</p>
<code><pre>
<span class=identifier>object </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>object </span><span class=identifier>x</span><span class=special>, </span><span class=identifier>object </span><span class=identifier>y</span><span class=special>) </span><span class=special>{
<span class=identifier>object </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>object </span><span class=identifier>x</span><span class=special>, </span><span class=identifier>object </span><span class=identifier>y</span><span class=special>) {
</span><span class=keyword>if </span><span class=special>(</span><span class=identifier>y </span><span class=special>== </span><span class=string>&quot;foo&quot;</span><span class=special>)
</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>slice</span><span class=special>(</span><span class=number>3</span><span class=special>,</span><span class=number>7</span><span class=special>) </span><span class=special>= </span><span class=string>&quot;bar&quot;</span><span class=special>;
</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>slice</span><span class=special>(</span><span class=number>3</span><span class=special>,</span><span class=number>7</span><span class=special>) = </span><span class=string>&quot;bar&quot;</span><span class=special>;
</span><span class=keyword>else
</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>&quot;items&quot;</span><span class=special>) </span><span class=special>+= </span><span class=identifier>y</span><span class=special>(</span><span class=number>3</span><span class=special>, </span><span class=identifier>x</span><span class=special>);
</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>&quot;items&quot;</span><span class=special>) += </span><span class=identifier>y</span><span class=special>(</span><span class=number>3</span><span class=special>, </span><span class=identifier>x</span><span class=special>);
</span><span class=keyword>return </span><span class=identifier>x</span><span class=special>;
</span><span class=special>}
</span><span class=identifier>object </span><span class=identifier>getfunc</span><span class=special>() </span><span class=special>{
}
</span><span class=identifier>object </span><span class=identifier>getfunc</span><span class=special>() {
</span><span class=keyword>return </span><span class=identifier>object</span><span class=special>(</span><span class=identifier>f</span><span class=special>);
</span><span class=special>}
}
</span></pre></code>
<p>
Apart from cosmetic differences due to the fact that we are writing the
@@ -68,7 +68,7 @@ coder.</p>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -1,186 +0,0 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Building an Extension Module </title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="class_data_members.html">
<link rel="next" href="inheritance.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><strong>Building
an Extension Module</strong></font> </td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><img src="theme/l_arr.gif" border="0"></td>
<td width="20"><img src="theme/r_arr.gif" border="0"></td>
</tr>
</table>
<h2>Building Boost.Python</h2>
<p>Every Boost.Python extension module must be linked with the boost_python shared
library. To build boost_python, use <a href="file:///C:/dev/boost/tools/build/index.html">Boost.Build</a>
in the usual way from the <tt>libs/python/build</tt> subdirectory of your boost
installation (if you have already built boost from the top level this may have
no effect, since the work is already done).</p>
<h2>Configuration</h2>
<p>You may need to configure the following variables to point Boost.Build at your
Python installation:</p>
<table width="95%" border="0" align="center">
<tr class="table_title">
<td width="24%">Variable Name</td>
<td width="20%">Semantics</td>
<td width="21%">Default</td>
<td width="35%">Notes</td>
</tr>
<tr class="table_cells">
<td><tt>PYTHON_ROOT</tt></td>
<td> The root directory of your Python installation</td>
<td>Windows: <tt><br>
c:/tools/python <br>
Unix: /usr/local</tt></td>
<td>On Unix, this is the <tt>--with-prefix=</tt> directory used to configure
Python</td>
</tr>
<tr class="table_cells">
<td><tt>PYTHON_VERSION</tt></td>
<td> The The 2-part python Major.Minor version number</td>
<td>Windows: 2.1 Unix: 1.5</td>
<td>Be sure not to include a third number, e.g. not &quot;2.2.1&quot;, even
if that's the version you have.</td>
</tr>
<tr class="table_cells">
<td><tt>PYTHON_INCLUDES</tt></td>
<td> path to Python <span class="preprocessor">#include</span> directories</td>
<td>Autoconfigured from <tt><br>
PYTHON_ROOT</tt></td>
<td>&nbsp;</td>
</tr>
<tr class="table_cells">
<td><tt>PYTHON_LIB_PATH</tt></td>
<td>path to Python library object.</td>
<td>Autoconfigured from <tt><br>
PYTHON_ROOT</tt></td>
<td>&nbsp;</td>
</tr>
<tr class="table_cells">
<td><tt>PYTHON_STDLIB_PATH</tt></td>
<td>path to Python standard library modules</td>
<td>Autoconfigured from <tt><br>
PYTHON_ROOT</tt></td>
<td>&nbsp;</td>
</tr>
<tr class="table_cells">
<td height="129"><tt>CYGWIN_ROOT</tt></td>
<td> path to the user's Cygwin installation</td>
<td>Autoconfigured from <tt><br>
PYTHON_ROOT</tt></td>
<td><a href="http://www.cygwin.com">Cygwin</a> only. This and the following
two settings are useful when building with multiple toolsets on Windows,
since Cygwin requires a different build of Python.</td>
</tr>
<tr class="table_cells">
<td height="21"><tt>GCC_PYTHON_ROOT</tt></td>
<td>path to the user's Cygwin Python installation</td>
<td><tt>$(CYGWIN_ROOT)<br>
/usr/local</tt></td>
<td> <a href="http://www.cygwin.com">Cygwin</a> only</td>
</tr>
<tr class="table_cells">
<td><tt>GCC_DEBUG_PYTHON_ROOT</tt></td>
<td> path to the user's Cygwin <a href="#variants">pydebug</a>
build</td>
<td><tt>$(CYGWIN_ROOT)<br>
/usr/local/pydebug</tt></td>
<td> <a href="http://www.cygwin.com">Cygwin</a> only</td>
</tr>
</table>
<h2>Results</h2>
<p>The build process will create a <tt>libs/python/build/bin-stage</tt> subdirectory
of the boost root (or of <tt>$(ALL_LOCATE_TARGET)</tt>, if you have set that
variable), containing the built libraries. The libraries are actually built
to unique directories for each toolset and variant elsewhere in the filesystem,
and copied to the bin-stage directory as a convenience, so if you build with
multiple toolsets at once, the product of later toolsets will overwrite that
of earlier toolsets in bin-stage.</p>
<h2>Testing</h2>
<p>To build and test Boost.Python from within the <tt>libs/python/build directory</tt>,
invoke</p>
<pre> bjam -sTOOLS=<a href="../../../tools/build/index.html">toolset</a> test</pre>
<p>This will update all of the Boost.Python v1 test and example targets. The tests
are relatively quiet by default. To get more-verbose output, you might try</p>
<pre> bjam -sTOOLS=<a href="../../../tools/build/index.html">toolset</a> -sPYTHON_TEST_ARGS=-v test</pre>
<p>which will print each test's Python code with the expected output as it passes.</p>
<h2>Building your Extension Module</h2>
<p>Though there are other approaches, the easiest way to build an extension module
using Boost.Python is with Boost.Build. Until Boost.Build v2 is released, cross-project
build dependencies are not supported, so it works most smoothly if you add a
new subproject to your boost installation. The <tt>libs/python/example</tt>
subdirectory of your boost installation contains a minimal example (along with
many extra sources). To copy the example subproject:</p>
<ol>
<li> Create a new subdirectory in,<tt> libs/python</tt>, say <tt>libs/python/my_project</tt>.</li>
<li> Copy <a href="../example/Jamfile"><tt>libs/python/example/Jamfile</tt></a>
to your new directory.</li>
<li> Edit the Jamfile as appropriate for your project. You'll want to change
the <tt>subproject</tt> rule invocation at the top, and the names of some
of the source files and/or targets.</li>
</ol>
<p>If you can't modify or copy your boost installation, the alternative is to
create your own Boost.Build project. A similar example you can use as a starting
point is available in <a href="../example/project.zip">this archive</a>. You'll
need to edit the Jamfile and Jamrules files, depending on the relative location
of your Boost installation and the new project. Note that automatic testing
of extension modules is not available in this configuration.</p>
<h2>Build Variants</h2>
<p>Three variant configurations of all python-related targets are supported, and
can be selected by setting the BUILD variable:</p>
<p> * <tt>release</tt> (optimization, <tt>-DNDEBUG</tt>)<br>
* <tt>debug</tt> (no optimization <tt>-D_DEBUG</tt>)<br>
* <tt>debug-python</tt> (no optimization, <tt>-D_DEBUG -DBOOST_DEBUG_PYTHON</tt>)</p>
<p>The first two variants of the boost_python library are built by default, and
are compatible with the default Python distribution. The debug-python variant
corresponds to a specially-built debugging version of Python. On Unix platforms,
this python is built by adding <tt>--with-pydebug</tt> when configuring the
Python build. On Windows, the debugging version of Python is generated by the
&quot;Win32 Debug&quot; target of the PCBuild.dsw Visual C++ 6.0 project in
the PCBuild subdirectory of your Python distribution. Extension modules built
with Python debugging enabled are not link-compatible with a non-debug build
of Python. Since few people actually have a debug build of Python (it doesn't
come with the standard distribution), the normal debug variant builds modules
which are compatible with ordinary Python.</p>
<p>On many windows compilers, when extension modules are built with <tt>-D_DEBUG</tt>,
Python defaults to force linking with a special debugging version of the Python
DLL. Since this debug DLL isn't supplied with the default Python installation
for Windows, Boost.Python uses <a href="../../../boost/python/detail/wrap_python.hpp"><tt>boost/python/detail/wrap_python.hpp</tt></a>
to temporarily undefine <tt>_DEBUG</tt> when <tt>Python.h</tt> is <span class="preprocessor">#included</span>
- unless <tt>BOOST_DEBUG_PYTHON</tt> is defined.</p>
<p>If you want the extra runtime checks available with the debugging version of
the library, <span class="preprocessor">#define</span> <tt>BOOST_DEBUG_PYTHON</tt>
to re-enable python debuggin, and link with the debug-python variant of boost_python.</p>
<p>If you do not <span class="preprocessor">#define</span> <tt>BOOST_DEBUG_PYTHON</tt>,
be sure that any source files in your extension module <span class="preprocessor">#include</span>
<tt>&lt;boost/python/detail/wrap_python.hpp&gt;</tt> instead of the usual <tt>Python.h</tt>,
or you will have link incompatibilities.</p>
<code></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><img src="theme/l_arr.gif" border="0"></td>
<td width="20"><img src="theme/r_arr.gif" border="0"></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -37,6 +37,11 @@ with every boost distribution: <b>bjam</b>.</p>
Besides bjam, there are of course other ways to get your module built.
What's written here should not be taken as &quot;the one and only way&quot;.
There are of course other build tools apart from <tt>bjam</tt>.
Take note however that the preferred build tool for Boost.Python is bjam.
There are so many ways to set up the build incorrectly. Experience shows
that 90% of the &quot;I can't build Boost.Python&quot; problems come from people
who had to use a different tool.
</td>
</tr>
</table>
@@ -182,7 +187,7 @@ You may now fire up Python and run our hello module:</p>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -4,7 +4,7 @@
<title>Call Policies</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="functions.html">
<link rel="next" href="default_arguments.html">
<link rel="next" href="overloading.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
@@ -21,7 +21,7 @@
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="default_arguments.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="20"><a href="overloading.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
@@ -43,9 +43,9 @@ How should the library wrap this function? A naive approach builds a
Python X object around result reference. This strategy might or might
not work out. Here's an example where it didn't</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>y</span><span class=special>, </span><span class=identifier>z</span><span class=special>) </span>#<span class=identifier>x </span><span class=identifier>refers </span><span class=identifier>to </span><span class=identifier>some </span><span class=identifier>C</span><span class=special>++ </span><span class=identifier>X
<span class=special>&gt;&gt;&gt; </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>y</span><span class=special>, </span><span class=identifier>z</span><span class=special>) </span>##<span class=identifier>x </span><span class=identifier>refers </span><span class=identifier>to </span><span class=identifier>some </span><span class=identifier>C</span><span class=special>++ </span><span class=identifier>X
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>del </span><span class=identifier>y
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>some_method</span><span class=special>() </span>#<span class=identifier>CRASH</span><span class=special>!
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>some_method</span><span class=special>() </span>##<span class=identifier>CRASH</span><span class=special>!
</span></pre></code>
<p>
What's the problem?</p>
@@ -53,10 +53,10 @@ What's the problem?</p>
Well, what if f() was implemented as shown below:</p>
<code><pre>
<span class=identifier>X</span><span class=special>&amp; </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>Y</span><span class=special>&amp; </span><span class=identifier>y</span><span class=special>, </span><span class=identifier>Z</span><span class=special>* </span><span class=identifier>z</span><span class=special>)
</span><span class=special>{
{
</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>z </span><span class=special>= </span><span class=identifier>z</span><span class=special>;
</span><span class=keyword>return </span><span class=identifier>y</span><span class=special>.</span><span class=identifier>x</span><span class=special>;
</span><span class=special>}
}
</span></pre></code>
<p>
The problem is that the lifetime of result X&amp; is tied to the lifetime
@@ -70,8 +70,8 @@ Here's what's happening:</p>
<ol><li><tt>f</tt> is called passing in a reference to <tt>y</tt> and a pointer to <tt>z</tt></li><li>A reference to <tt>y.x</tt> is returned</li><li><tt>y</tt> is deleted. <tt>x</tt> is a dangling reference</li><li><tt>x.some_method()</tt> is called</li><li><b>BOOM!</b></li></ol><p>
We could copy result into a new object:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>y</span><span class=special>, </span><span class=identifier>z</span><span class=special>).</span><span class=identifier>set</span><span class=special>(</span><span class=number>42</span><span class=special>) </span>#<span class=identifier>Result </span><span class=identifier>disappears
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>y</span><span class=special>.</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>get</span><span class=special>() </span>#<span class=identifier>No </span><span class=identifier>crash</span><span class=special>, </span><span class=identifier>but </span><span class=identifier>still </span><span class=identifier>bad
<span class=special>&gt;&gt;&gt; </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>y</span><span class=special>, </span><span class=identifier>z</span><span class=special>).</span><span class=identifier>set</span><span class=special>(</span><span class=number>42</span><span class=special>) </span>##<span class=identifier>Result </span><span class=identifier>disappears
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>y</span><span class=special>.</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>get</span><span class=special>() </span>##<span class=identifier>No </span><span class=identifier>crash</span><span class=special>, </span><span class=identifier>but </span><span class=identifier>still </span><span class=identifier>bad
</span><span class=number>3.14
</span></pre></code>
<p>
@@ -84,25 +84,25 @@ Our problems do not end there. Suppose Y is implemented as follows:</p>
<span class=keyword>struct </span><span class=identifier>Y
</span><span class=special>{
</span><span class=identifier>X </span><span class=identifier>x</span><span class=special>; </span><span class=identifier>Z</span><span class=special>* </span><span class=identifier>z</span><span class=special>;
</span><span class=keyword>int </span><span class=identifier>z_value</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>z</span><span class=special>-&gt;</span><span class=identifier>value</span><span class=special>(); </span><span class=special>}
</span><span class=special>};
</span><span class=keyword>int </span><span class=identifier>z_value</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>z</span><span class=special>-&gt;</span><span class=identifier>value</span><span class=special>(); }
};
</span></pre></code>
<p>
Notice that the data member <tt>z</tt> is held by class Y using a raw
pointer. Now we have a potential dangling pointer problem inside Y:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>y</span><span class=special>, </span><span class=identifier>z</span><span class=special>) </span>#<span class=identifier>y </span><span class=identifier>refers </span><span class=identifier>to </span><span class=identifier>z
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>del </span><span class=identifier>z </span>#<span class=identifier>Kill </span><span class=identifier>the </span><span class=identifier>z </span><span class=identifier>object
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>y</span><span class=special>.</span><span class=identifier>z_value</span><span class=special>() </span>#<span class=identifier>CRASH</span><span class=special>!
<span class=special>&gt;&gt;&gt; </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>y</span><span class=special>, </span><span class=identifier>z</span><span class=special>) </span>##<span class=identifier>y </span><span class=identifier>refers </span><span class=identifier>to </span><span class=identifier>z
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>del </span><span class=identifier>z </span>##<span class=identifier>Kill </span><span class=identifier>the </span><span class=identifier>z </span><span class=identifier>object
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>y</span><span class=special>.</span><span class=identifier>z_value</span><span class=special>() </span>##<span class=identifier>CRASH</span><span class=special>!
</span></pre></code>
<p>
For reference, here's the implementation of <tt>f</tt> again:</p>
<code><pre>
<span class=identifier>X</span><span class=special>&amp; </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>Y</span><span class=special>&amp; </span><span class=identifier>y</span><span class=special>, </span><span class=identifier>Z</span><span class=special>* </span><span class=identifier>z</span><span class=special>)
</span><span class=special>{
{
</span><span class=identifier>y</span><span class=special>.</span><span class=identifier>z </span><span class=special>= </span><span class=identifier>z</span><span class=special>;
</span><span class=keyword>return </span><span class=identifier>y</span><span class=special>.</span><span class=identifier>x</span><span class=special>;
</span><span class=special>}
}
</span></pre></code>
<p>
Here's what's happening:</p>
@@ -113,7 +113,7 @@ are our friends:</p>
<code><pre>
<span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>f</span><span class=special>,
</span><span class=identifier>return_internal_reference</span><span class=special>&lt;</span><span class=number>1</span><span class=special>,
</span><span class=identifier>with_custodian_and_ward</span><span class=special>&lt;</span><span class=number>1</span><span class=special>, </span><span class=number>2</span><span class=special>&gt; </span><span class=special>&gt;());
</span><span class=identifier>with_custodian_and_ward</span><span class=special>&lt;</span><span class=number>1</span><span class=special>, </span><span class=number>2</span><span class=special>&gt; &gt;());
</span></pre></code>
<p>
What are the <tt>1</tt> and <tt>2</tt> parameters, you ask?</p>
@@ -138,7 +138,7 @@ or more policies can be composed by chaining. Here's the general syntax:</p>
<code><pre>
<span class=identifier>policy1</span><span class=special>&lt;</span><span class=identifier>args</span><span class=special>...,
</span><span class=identifier>policy2</span><span class=special>&lt;</span><span class=identifier>args</span><span class=special>...,
</span><span class=identifier>policy3</span><span class=special>&lt;</span><span class=identifier>args</span><span class=special>...&gt; </span><span class=special>&gt; </span><span class=special>&gt;
</span><span class=identifier>policy3</span><span class=special>&lt;</span><span class=identifier>args</span><span class=special>...&gt; &gt; &gt;
</span></pre></code>
<p>
Here is the list of predefined call policies. A complete reference detailing
@@ -156,11 +156,11 @@ here</a>.</p>
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="default_arguments.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="20"><a href="overloading.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -32,23 +32,24 @@ member that we wish to be exposed may be regarded as <b>read-only</b> or
<code><pre>
<span class=keyword>struct </span><span class=identifier>Var
</span><span class=special>{
</span><span class=identifier>Var</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>name</span><span class=special>) </span><span class=special>: </span><span class=identifier>name</span><span class=special>(</span><span class=identifier>name</span><span class=special>), </span><span class=identifier>value</span><span class=special>() </span><span class=special>{}
</span><span class=identifier>Var</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>name</span><span class=special>) : </span><span class=identifier>name</span><span class=special>(</span><span class=identifier>name</span><span class=special>), </span><span class=identifier>value</span><span class=special>() {}
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=keyword>const </span><span class=identifier>name</span><span class=special>;
</span><span class=keyword>float </span><span class=identifier>value</span><span class=special>;
</span><span class=special>};
};
</span></pre></code>
<p>
Our C++ <tt>Var</tt> class and its data members can be exposed to Python:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Var</span><span class=special>&gt;(</span><span class=string>&quot;Var&quot;</span><span class=special>, </span><span class=identifier>init</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;())
</span><span class=special>.</span><span class=identifier>def_readonly</span><span class=special>(</span><span class=string>&quot;name&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>name</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def_readwrite</span><span class=special>(</span><span class=string>&quot;value&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>value</span><span class=special>);
.</span><span class=identifier>def_readonly</span><span class=special>(</span><span class=string>&quot;name&quot;</span><span class=special>, &amp;</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>name</span><span class=special>)
.</span><span class=identifier>def_readwrite</span><span class=special>(</span><span class=string>&quot;value&quot;</span><span class=special>, &amp;</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>value</span><span class=special>);
</span></pre></code>
<p>
Then, in Python:</p>
Then, in Python, assuming we have placed our Var class inside the namespace
hello as we did before:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>Var</span><span class=special>(</span><span class=literal>'pi'</span><span class=special>)
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>value </span><span class=special>= </span><span class=number>3.14
<span class=special>&gt;&gt;&gt; </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>hello</span><span class=special>.</span><span class=identifier>Var</span><span class=special>(</span><span class=literal>'pi'</span><span class=special>)
&gt;&gt;&gt; </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>value </span><span class=special>= </span><span class=number>3.14
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>print </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>name</span><span class=special>, </span><span class=literal>'is around'</span><span class=special>, </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>value
</span><span class=identifier>pi </span><span class=identifier>is </span><span class=identifier>around </span><span class=number>3.14
</span></pre></code>
@@ -68,7 +69,7 @@ as <b>read-write</b>.</p>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -3,7 +3,7 @@
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Class Operators/Special Functions</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="class_virtual_functions.html">
<link rel="prev" href="virtual_functions_with_default_implementations.html">
<link rel="next" href="functions.html">
</head>
<body>
@@ -20,7 +20,7 @@
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_virtual_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="30"><a href="virtual_functions_with_default_implementations.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
@@ -32,7 +32,7 @@ this and makes it easy to wrap C++ operator-powered classes.</p>
Consider a file position class <tt>FilePos</tt> and a set of operators that take
on FilePos instances:</p>
<code><pre>
<span class=keyword>class </span><span class=identifier>FilePos </span><span class=special>{ </span><span class=comment>/*...*/ </span><span class=special>};
<span class=keyword>class </span><span class=identifier>FilePos </span><span class=special>{ /*...*/ };
</span><span class=identifier>FilePos </span><span class=keyword>operator</span><span class=special>+(</span><span class=identifier>FilePos</span><span class=special>, </span><span class=keyword>int</span><span class=special>);
</span><span class=identifier>FilePos </span><span class=keyword>operator</span><span class=special>+(</span><span class=keyword>int</span><span class=special>, </span><span class=identifier>FilePos</span><span class=special>);
@@ -47,13 +47,13 @@ The class and the various operators can be mapped to Python rather easily
and intuitively:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>FilePos</span><span class=special>&gt;(</span><span class=string>&quot;FilePos&quot;</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>self </span><span class=special>+ </span><span class=keyword>int</span><span class=special>()) </span><span class=comment>// __add__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=keyword>int</span><span class=special>() </span><span class=special>+ </span><span class=identifier>self</span><span class=special>) </span><span class=comment>// __radd__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>self </span><span class=special>- </span><span class=identifier>self</span><span class=special>) </span><span class=comment>// __sub__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>self </span><span class=special>- </span><span class=keyword>int</span><span class=special>()) </span><span class=comment>// __rsub__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>self </span><span class=special>+= </span><span class=keyword>int</span><span class=special>()) </span><span class=comment>// __iadd__
.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>self </span><span class=special>+ </span><span class=keyword>int</span><span class=special>()) // </span><span class=identifier>__add__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=keyword>int</span><span class=special>() + </span><span class=identifier>self</span><span class=special>) // </span><span class=identifier>__radd__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>self </span><span class=special>- </span><span class=identifier>self</span><span class=special>) // </span><span class=identifier>__sub__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>self </span><span class=special>- </span><span class=keyword>int</span><span class=special>()) // </span><span class=identifier>__sub__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>self </span><span class=special>+= </span><span class=keyword>int</span><span class=special>()) // </span><span class=identifier>__iadd__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>self </span><span class=special>-= </span><span class=identifier>other</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;())
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>self </span><span class=special>&lt; </span><span class=identifier>self</span><span class=special>); </span><span class=comment>// __lt__
.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>self </span><span class=special>&lt; </span><span class=identifier>self</span><span class=special>); // </span><span class=identifier>__lt__
</span></pre></code>
<p>
The code snippet above is very clear and needs almost no explanation at
@@ -69,17 +69,17 @@ similar set of intuitive interfaces can also be used to wrap C++ functions
that correspond to these Python <i>special functions</i>. Example:</p>
<code><pre>
<span class=keyword>class </span><span class=identifier>Rational
</span><span class=special>{ </span><span class=keyword>operator </span><span class=keyword>double</span><span class=special>() </span><span class=keyword>const</span><span class=special>; </span><span class=special>};
</span><span class=special>{ </span><span class=keyword>operator </span><span class=keyword>double</span><span class=special>() </span><span class=keyword>const</span><span class=special>; };
</span><span class=identifier>Rational </span><span class=identifier>pow</span><span class=special>(</span><span class=identifier>Rational</span><span class=special>, </span><span class=identifier>Rational</span><span class=special>);
</span><span class=identifier>Rational </span><span class=identifier>abs</span><span class=special>(</span><span class=identifier>Rational</span><span class=special>);
</span><span class=identifier>ostream</span><span class=special>&amp; </span><span class=keyword>operator</span><span class=special>&lt;&lt;(</span><span class=identifier>ostream</span><span class=special>&amp;,</span><span class=identifier>Rational</span><span class=special>);
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Rational</span><span class=special>&gt;()
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>float_</span><span class=special>(</span><span class=identifier>self</span><span class=special>)) </span><span class=comment>// __float__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>pow</span><span class=special>(</span><span class=identifier>self</span><span class=special>, </span><span class=identifier>other</span><span class=special>&lt;</span><span class=identifier>Rational</span><span class=special>&gt;)) </span><span class=comment>// __pow__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>abs</span><span class=special>(</span><span class=identifier>self</span><span class=special>)) </span><span class=comment>// __abs__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>str</span><span class=special>(</span><span class=identifier>self</span><span class=special>)) </span><span class=comment>// __str__
.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>float_</span><span class=special>(</span><span class=identifier>self</span><span class=special>)) // </span><span class=identifier>__float__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>pow</span><span class=special>(</span><span class=identifier>self</span><span class=special>, </span><span class=identifier>other</span><span class=special>&lt;</span><span class=identifier>Rational</span><span class=special>&gt;)) // </span><span class=identifier>__pow__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>abs</span><span class=special>(</span><span class=identifier>self</span><span class=special>)) // </span><span class=identifier>__abs__
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>str</span><span class=special>(</span><span class=identifier>self</span><span class=special>)) // </span><span class=identifier>__str__
</span><span class=special>;
</span></pre></code>
<p>
@@ -95,12 +95,12 @@ Well, the method <tt>str</tt> requires the <tt>operator&lt;&lt;</tt> to do its w
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_virtual_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="30"><a href="virtual_functions_with_default_implementations.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -36,8 +36,8 @@ properties. Here's an example:</p>
</span><span class=identifier>Num</span><span class=special>();
</span><span class=keyword>float </span><span class=identifier>get</span><span class=special>() </span><span class=keyword>const</span><span class=special>;
</span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=keyword>float </span><span class=identifier>value</span><span class=special>);
</span><span class=special>...
</span><span class=special>};
...
};
</span></pre></code>
<p>
However, in Python attribute access is fine; it doesn't neccessarily break
@@ -46,23 +46,23 @@ attributes can just be a different syntax for a method call. Wrapping our
<tt>Num</tt> class using Boost.Python:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Num</span><span class=special>&gt;(</span><span class=string>&quot;Num&quot;</span><span class=special>)
</span><span class=special>.</span><span class=identifier>add_property</span><span class=special>(</span><span class=string>&quot;rovalue&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>get</span><span class=special>)
</span><span class=special>.</span><span class=identifier>add_property</span><span class=special>(</span><span class=string>&quot;value&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>get</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>set</span><span class=special>);
.</span><span class=identifier>add_property</span><span class=special>(</span><span class=string>&quot;rovalue&quot;</span><span class=special>, &amp;</span><span class=identifier>Num</span><span class=special>::</span><span class=identifier>get</span><span class=special>)
.</span><span class=identifier>add_property</span><span class=special>(</span><span class=string>&quot;value&quot;</span><span class=special>, &amp;</span><span class=identifier>Num</span><span class=special>::</span><span class=identifier>get</span><span class=special>, &amp;</span><span class=identifier>Num</span><span class=special>::</span><span class=identifier>set</span><span class=special>);
</span></pre></code>
<p>
And at last, in Python:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>Num</span><span class=special>()
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>value </span><span class=special>= </span><span class=number>3.14
&gt;&gt;&gt; </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>value </span><span class=special>= </span><span class=number>3.14
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>value</span><span class=special>, </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>rovalue
</span><span class=special>(</span><span class=number>3.14</span><span class=special>, </span><span class=number>3.14</span><span class=special>)
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>rovalue </span><span class=special>= </span><span class=number>2.17 </span>#<span class=identifier>error</span><span class=special>!
&gt;&gt;&gt; </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>rovalue </span><span class=special>= </span><span class=number>2.17 </span>##<span class=identifier>error</span><span class=special>!
</span></pre></code>
<p>
Take note that the class property <tt>rovalue</tt> is exposed as <b>read-only</b>
since the <tt>rovalue</tt> setter member function is not passed in:</p>
<code><pre>
<span class=special>.</span><span class=identifier>add_property</span><span class=special>(</span><span class=string>&quot;rovalue&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>get</span><span class=special>)
<span class=special>.</span><span class=identifier>add_property</span><span class=special>(</span><span class=string>&quot;rovalue&quot;</span><span class=special>, &amp;</span><span class=identifier>Num</span><span class=special>::</span><span class=identifier>get</span><span class=special>)
</span></pre></code>
<table border="0">
<tr>
@@ -72,7 +72,7 @@ since the <tt>rovalue</tt> setter member function is not passed in:</p>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -4,7 +4,7 @@
<title>Class Virtual Functions</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="inheritance.html">
<link rel="next" href="class_operators_special_functions.html">
<link rel="next" href="deriving_a_python_class.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
@@ -21,7 +21,7 @@
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="inheritance.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_operators_special_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="20"><a href="deriving_a_python_class.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
@@ -31,8 +31,8 @@ add a virtual function to our <tt>Base</tt> class:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>Base
</span><span class=special>{
</span><span class=keyword>virtual </span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() </span><span class=special>= </span><span class=number>0</span><span class=special>;
</span><span class=special>};
</span><span class=keyword>virtual </span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() = </span><span class=number>0</span><span class=special>;
};
</span></pre></code>
<p>
Since <tt>f</tt> is a pure virtual function, <tt>Base</tt> is now an abstract
@@ -40,7 +40,7 @@ class. Given an instance of our class, the free function <tt>call_f</tt>
calls some implementation of this virtual function in a concrete
derived class:</p>
<code><pre>
<span class=keyword>int </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>Base</span><span class=special>&amp; </span><span class=identifier>b</span><span class=special>) </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>b</span><span class=special>.</span><span class=identifier>f</span><span class=special>(); </span><span class=special>}
<span class=keyword>int </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>Base</span><span class=special>&amp; </span><span class=identifier>b</span><span class=special>) { </span><span class=keyword>return </span><span class=identifier>b</span><span class=special>.</span><span class=identifier>f</span><span class=special>(); }
</span></pre></code>
<p>
To allow this function to be implemented in a Python derived class, we
@@ -49,10 +49,10 @@ need to create a class wrapper:</p>
<span class=keyword>struct </span><span class=identifier>BaseWrap </span><span class=special>: </span><span class=identifier>Base
</span><span class=special>{
</span><span class=identifier>BaseWrap</span><span class=special>(</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self_</span><span class=special>)
</span><span class=special>: </span><span class=identifier>self</span><span class=special>(</span><span class=identifier>self_</span><span class=special>) </span><span class=special>{}
</span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>call_method</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;(</span><span class=identifier>self</span><span class=special>, </span><span class=string>&quot;f&quot;</span><span class=special>); </span><span class=special>}
: </span><span class=identifier>self</span><span class=special>(</span><span class=identifier>self_</span><span class=special>) {}
</span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>call_method</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;(</span><span class=identifier>self</span><span class=special>, </span><span class=string>&quot;f&quot;</span><span class=special>); }
</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self</span><span class=special>;
</span><span class=special>};
};
</span></pre></code>
<table width="80%" border="0" align="center">
<tr>
@@ -93,7 +93,7 @@ polymorphically <i>from</i> <b>C++</b>. </td>
Wrapping <tt>Base</tt> and the free function <tt>call_f</tt>:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>, </span><span class=identifier>BaseWrap</span><span class=special>, </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>noncopyable</span><span class=special>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>, </span><span class=identifier>no_init</span><span class=special>)
</span><span class=special>;
;
</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;call_f&quot;</span><span class=special>, </span><span class=identifier>call_f</span><span class=special>);
</span></pre></code>
<p>
@@ -106,119 +106,21 @@ available, since Base is an abstract class.</p>
In Python, let us try to instantiate our <tt>Base</tt> class:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>base </span><span class=special>= </span><span class=identifier>Base</span><span class=special>()
</span><span class=identifier>AttributeError</span><span class=special>: </span><span class=special>...
</span><span class=identifier>RuntimeError</span><span class=special>: </span><span class=identifier>This </span><span class=keyword>class </span><span class=identifier>cannot </span><span class=identifier>be </span><span class=identifier>instantiated </span><span class=identifier>from </span><span class=identifier>Python
</span></pre></code>
<p>
Why is it an error? <tt>Base</tt> is an abstract class. As such it is advisable
to define the Python wrapper with <tt>no_init</tt> as we have done above. Doing
so will disallow abstract base classes such as <tt>Base</tt> to be instantiated.</p>
<a name="deriving_a_python_class"></a><h2>Deriving a Python class</h2><p>
Now, at last, we can even derive from our base class <tt>Base</tt> in Python:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=keyword>class </span><span class=identifier>Derived</span><span class=special>(</span><span class=identifier>Base</span><span class=special>):
</span><span class=special>... </span><span class=identifier>def </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
</span><span class=special>... </span><span class=keyword>return </span><span class=number>42
</span><span class=special>...
</span></pre></code>
<p>
Cool eh? A Python class deriving from a C++ class!</p>
<p>
Let's now make an instance of our Python class <tt>Derived</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived </span><span class=special>= </span><span class=identifier>Derived</span><span class=special>()
</span></pre></code>
<p>
Calling <tt>derived.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>42
</span></pre></code>
<p>
Will yield the expected result. Finally, calling calling the free function
<tt>call_f</tt> with <tt>derived</tt> as argument:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>derived</span><span class=special>)
</span><span class=number>42
</span></pre></code>
<p>
Will also yield the expected result.</p>
<p>
Here's what's happening:</p>
<ol><li><tt>call_f(derived)</tt> is called in Python</li><li>This corresponds to <tt>def(&quot;call_f&quot;, call_f);</tt>. Boost.Python dispatches this call.</li><li><tt>int call_f(Base&amp; b) { return b.f(); }</tt> accepts the call.</li><li>The overridden virtual function <tt>f</tt> of <tt>BaseWrap</tt> is called.</li><li><tt>call_method&lt;int&gt;(self, &quot;f&quot;);</tt> dispatches the call back to Python.</li><li><tt>def f(self): return 42</tt> is finally called.</li></ol><p>
Rewind back to our <tt>Base</tt> class, if its member function <tt>f</tt> was not
declared as pure virtual:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>Base
</span><span class=special>{
</span><span class=keyword>virtual </span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=number>0</span><span class=special>; </span><span class=special>}
</span><span class=special>};
</span></pre></code>
<p>
And instead is implemented to return <tt>0</tt>, as shown above.</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>BaseWrap </span><span class=special>: </span><span class=identifier>Base
</span><span class=special>{
</span><span class=identifier>BaseWrap</span><span class=special>(</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self_</span><span class=special>)
</span><span class=special>: </span><span class=identifier>self</span><span class=special>(</span><span class=identifier>self_</span><span class=special>) </span><span class=special>{}
</span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>call_method</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;(</span><span class=identifier>self</span><span class=special>, </span><span class=string>&quot;f&quot;</span><span class=special>); </span><span class=special>}
</span><span class=keyword>static </span><span class=keyword>int </span><span class=identifier>default_f</span><span class=special>(</span><span class=identifier>Base</span><span class=special>* </span><span class=identifier>b</span><span class=special>) </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>b</span><span class=special>-&gt;</span><span class=identifier>Base</span><span class=special>::</span><span class=identifier>f</span><span class=special>(); </span><span class=special>} </span><span class=comment>// &lt;&lt;=== added
</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self</span><span class=special>;
</span><span class=special>};
</span></pre></code>
<p>
then, our Boost.Python wrapper:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>, </span><span class=identifier>BaseWrap</span><span class=special>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>BaseWrap</span><span class=special>::</span><span class=identifier>default_f</span><span class=special>)
</span><span class=special>;
</span></pre></code>
<p>
Note that we are allowing <tt>Base</tt> objects to be instantiated this time,
unlike before where we specifically defined the <tt>class_&lt;Base&gt;</tt> with
<tt>no_init</tt>.</p>
<p>
In Python, the results would be as expected:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>base </span><span class=special>= </span><span class=identifier>Base</span><span class=special>()
</span><span class=special>&gt;&gt;&gt; </span><span class=keyword>class </span><span class=identifier>Derived</span><span class=special>(</span><span class=identifier>Base</span><span class=special>):
</span><span class=special>... </span><span class=identifier>def </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
</span><span class=special>... </span><span class=keyword>return </span><span class=number>42
</span><span class=special>...
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>derived </span><span class=special>= </span><span class=identifier>Derived</span><span class=special>()
</span></pre></code>
<p>
Calling <tt>base.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>base</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>0
</span></pre></code>
<p>
Calling <tt>derived.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>42
</span></pre></code>
<p>
Calling <tt>call_f</tt>, passing in a <tt>base</tt> object:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>base</span><span class=special>)
</span><span class=number>0
</span></pre></code>
<p>
Calling <tt>call_f</tt>, passing in a <tt>derived</tt> object:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>derived</span><span class=special>)
</span><span class=number>42
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="inheritance.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_operators_special_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="20"><a href="deriving_a_python_class.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -38,11 +38,11 @@ build on our previous example:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>World
</span><span class=special>{
</span><span class=identifier>World</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>): </span><span class=identifier>msg</span><span class=special>(</span><span class=identifier>msg</span><span class=special>) </span><span class=special>{} </span><span class=comment>// added constructor
</span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>) </span><span class=special>{ </span><span class=keyword>this</span><span class=special>-&gt;</span><span class=identifier>msg </span><span class=special>= </span><span class=identifier>msg</span><span class=special>; </span><span class=special>}
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>greet</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>msg</span><span class=special>; </span><span class=special>}
</span><span class=identifier>World</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>): </span><span class=identifier>msg</span><span class=special>(</span><span class=identifier>msg</span><span class=special>) {} // </span><span class=identifier>added </span><span class=identifier>constructor
</span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>) { </span><span class=keyword>this</span><span class=special>-&gt;</span><span class=identifier>msg </span><span class=special>= </span><span class=identifier>msg</span><span class=special>; }
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>greet</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>msg</span><span class=special>; }
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>;
</span><span class=special>};
};
</span></pre></code>
<p>
This time <tt>World</tt> has no default constructor; our previous
@@ -54,12 +54,12 @@ expose instead.</p>
</span><span class=keyword>using </span><span class=keyword>namespace </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>python</span><span class=special>;
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>hello</span><span class=special>)
</span><span class=special>{
{
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>World</span><span class=special>&gt;(</span><span class=string>&quot;World&quot;</span><span class=special>, </span><span class=identifier>init</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;())
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;greet&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>greet</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;set&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>set</span><span class=special>)
</span><span class=special>;
</span><span class=special>}
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;greet&quot;</span><span class=special>, &amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>greet</span><span class=special>)
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;set&quot;</span><span class=special>, &amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>set</span><span class=special>)
;
}
</span></pre></code>
<p>
<tt>init&lt;std::string&gt;()</tt> exposes the constructor taking in a
@@ -71,10 +71,10 @@ the <tt>def()</tt> member function. Say for example we have another World
constructor taking in two doubles:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>World</span><span class=special>&gt;(</span><span class=string>&quot;World&quot;</span><span class=special>, </span><span class=identifier>init</span><span class=special>&lt;</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>&gt;())
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>init</span><span class=special>&lt;</span><span class=keyword>double</span><span class=special>, </span><span class=keyword>double</span><span class=special>&gt;())
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;greet&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>greet</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;set&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>set</span><span class=special>)
</span><span class=special>;
.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>init</span><span class=special>&lt;</span><span class=keyword>double</span><span class=special>, </span><span class=keyword>double</span><span class=special>&gt;())
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;greet&quot;</span><span class=special>, &amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>greet</span><span class=special>)
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;set&quot;</span><span class=special>, &amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>set</span><span class=special>)
;
</span></pre></code>
<p>
On the other hand, if we do not wish to expose any constructors at
@@ -93,7 +93,7 @@ Python RuntimeError exception.</p>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -0,0 +1,210 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Creating Packages</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="general_techniques.html">
<link rel="next" href="extending_wrapped_objects_in_python.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Creating Packages</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="general_techniques.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="extending_wrapped_objects_in_python.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
A Python package is a collection of modules that provide to the user a certain
functionality. If you're not familiar on how to create packages, a good
introduction to them is provided in the
<a href="http://www.python.org/doc/current/tut/node8.html">
Python Tutorial</a>.</p>
<p>
But we are wrapping C++ code, using Boost.Python. How can we provide a nice
package interface to our users? To better explain some concepts, let's work
with an example.</p>
<p>
We have a C++ library that works with sounds: reading and writing various
formats, applying filters to the sound data, etc. It is named (conveniently)
<tt>sounds</tt>. Our library already has a neat C++ namespace hierarchy, like so: </p>
<code><pre>
<span class=identifier>sounds</span><span class=special>::</span><span class=identifier>core
</span><span class=identifier>sounds</span><span class=special>::</span><span class=identifier>io
</span><span class=identifier>sounds</span><span class=special>::</span><span class=identifier>filters
</span></pre></code>
<p>
We would like to present this same hierarchy to the Python user, allowing him
to write code like this:</p>
<code><pre>
<span class=identifier>import </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters
</span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters</span><span class=special>.</span><span class=identifier>echo</span><span class=special>(...) </span>##<span class=identifier>echo </span><span class=identifier>is </span><span class=identifier>a </span><span class=identifier>C</span><span class=special>++ </span><span class=identifier>function
</span></pre></code>
<p>
The first step is to write the wrapping code. We have to export each module
separately with Boost.Python, like this:</p>
<code><pre>
<span class=comment>/* file core.cpp */
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>core</span><span class=special>)
{
/* </span><span class=keyword>export </span><span class=identifier>everything </span><span class=identifier>in </span><span class=identifier>the </span><span class=identifier>sounds</span><span class=special>::</span><span class=identifier>core </span><span class=keyword>namespace </span><span class=special>*/
...
}
/* </span><span class=identifier>file </span><span class=identifier>io</span><span class=special>.</span><span class=identifier>cpp </span><span class=special>*/
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>io</span><span class=special>)
{
/* </span><span class=keyword>export </span><span class=identifier>everything </span><span class=identifier>in </span><span class=identifier>the </span><span class=identifier>sounds</span><span class=special>::</span><span class=identifier>io </span><span class=keyword>namespace </span><span class=special>*/
...
}
/* </span><span class=identifier>file </span><span class=identifier>filters</span><span class=special>.</span><span class=identifier>cpp </span><span class=special>*/
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>filters</span><span class=special>)
{
/* </span><span class=keyword>export </span><span class=identifier>everything </span><span class=identifier>in </span><span class=identifier>the </span><span class=identifier>sounds</span><span class=special>::</span><span class=identifier>filters </span><span class=keyword>namespace </span><span class=special>*/
...
}
</span></pre></code>
<p>
Compiling these files will generate the following Python extensions:
<tt>core.pyd</tt>, <tt>io.pyd</tt> and <tt>filters.pyd</tt>.</p>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img> The extension <tt>.pyd</tt> is used for python extension modules, which
are just shared libraries. Using the default for your system, like <tt>.so</tt> for
Unix and <tt>.dll</tt> for Windows, works just as well. </td>
</tr>
</table>
<p>
Now, we create this directory structure for our Python package:</p>
<code><pre>
sounds/
__init__.py
core.pyd
filters.pyd
io.pyd
</pre></code><p>
The file <tt>__init__.py</tt> is what tells Python that the directory <tt>sounds/</tt> is
actually a Python package. It can be a empty file, but can also perform some
magic, that will be shown later. </p>
<p>
Now our package is ready. All the user has to do is put <tt>sounds</tt> into his
<a href="http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000">
PYTHONPATH</a> and fire up the interpreter:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>io
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>sound </span><span class=special>= </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>io</span><span class=special>.</span><span class=identifier>open</span><span class=special>(</span><span class=literal>'file.mp3'</span><span class=special>)
&gt;&gt;&gt; </span><span class=identifier>new_sound </span><span class=special>= </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters</span><span class=special>.</span><span class=identifier>echo</span><span class=special>(</span><span class=identifier>sound</span><span class=special>, </span><span class=number>1.0</span><span class=special>)
</span></pre></code>
<p>
Nice heh? </p>
<p>
This is the simplest way to create hierarchies of packages, but it is not very
flexible. What if we want to add a <i>pure</i> Python function to the filters
package, for instance, one that applies 3 filters in a sound object at once?
Sure, you can do this in C++ and export it, but why not do so in Python? You
don't have to recompile the extension modules, plus it will be easier to write
it.</p>
<p>
If we want this flexibility, we will have to complicate our package hierarchy a
little. First, we will have to change the name of the extension modules:</p>
<code><pre>
<span class=comment>/* file core.cpp */
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>_core</span><span class=special>)
{
...
/* </span><span class=keyword>export </span><span class=identifier>everything </span><span class=identifier>in </span><span class=identifier>the </span><span class=identifier>sounds</span><span class=special>::</span><span class=identifier>core </span><span class=keyword>namespace </span><span class=special>*/
}
</span></pre></code>
<p>
Note that we added an underscore to the module name. The filename will have to
be changed to <tt>_core.pyd</tt> as well, and we do the same to the other extension modules.
Now, we change our package hierarchy like so:</p>
<code><pre>
sounds/
__init__.py
core/
__init__.py
_core.pyd
filters/
__init__.py
_filters.pyd
io/
__init__.py
_io.pyd
</pre></code><p>
Note that we created a directory for each extension module, and added a
__init__.py to each one. But if we leave it that way, the user will have to
access the functions in the core module with this syntax: </p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>core</span><span class=special>.</span><span class=identifier>_core
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>core</span><span class=special>.</span><span class=identifier>_core</span><span class=special>.</span><span class=identifier>foo</span><span class=special>(...)
</span></pre></code>
<p>
which is not what we want. But here enters the <tt>__init__.py</tt> magic: everything
that is brought to the <tt>__init__.py</tt> namespace can be accessed directly by the
user. So, all we have to do is bring the entire namespace from <tt>_core.pyd</tt>
to <tt>core/__init__.py</tt>. So add this line of code to <tt>sounds/core/__init__.py</tt>:</p>
<code><pre>
<span class=identifier>from </span><span class=identifier>_core </span><span class=identifier>import </span><span class=special>*
</span></pre></code>
<p>
We do the same for the other packages. Now the user accesses the functions and
classes in the extension modules like before:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters</span><span class=special>.</span><span class=identifier>echo</span><span class=special>(...)
</span></pre></code>
<p>
with the additional benefit that we can easily add pure Python functions to
any module, in a way that the user can't tell the difference between a C++
function and a Python function. Let's add a <i>pure</i> Python function,
<tt>echo_noise</tt>, to the <tt>filters</tt> package. This function applies both the
<tt>echo</tt> and <tt>noise</tt> filters in sequence in the given <tt>sound</tt> object. We
create a file named <tt>sounds/filters/echo_noise.py</tt> and code our function:</p>
<code><pre>
<span class=identifier>import </span><span class=identifier>_filters
</span><span class=identifier>def </span><span class=identifier>echo_noise</span><span class=special>(</span><span class=identifier>sound</span><span class=special>):
</span><span class=identifier>s </span><span class=special>= </span><span class=identifier>_filters</span><span class=special>.</span><span class=identifier>echo</span><span class=special>(</span><span class=identifier>sound</span><span class=special>)
</span><span class=identifier>s </span><span class=special>= </span><span class=identifier>_filters</span><span class=special>.</span><span class=identifier>noise</span><span class=special>(</span><span class=identifier>sound</span><span class=special>)
</span><span class=keyword>return </span><span class=identifier>s
</span></pre></code>
<p>
Next, we add this line to <tt>sounds/filters/__init__.py</tt>:</p>
<code><pre>
<span class=identifier>from </span><span class=identifier>echo_noise </span><span class=identifier>import </span><span class=identifier>echo_noise
</span></pre></code>
<p>
And that's it. The user now accesses this function like any other function
from the <tt>filters</tt> package:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>sounds</span><span class=special>.</span><span class=identifier>filters</span><span class=special>.</span><span class=identifier>echo_noise</span><span class=special>(...)
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="general_techniques.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="extending_wrapped_objects_in_python.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -3,8 +3,8 @@
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Default Arguments</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="call_policies.html">
<link rel="next" href="object_interface.html">
<link rel="prev" href="overloading.html">
<link rel="next" href="auto_overloading.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
@@ -20,8 +20,8 @@
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="call_policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="object_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="30"><a href="overloading.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="auto_overloading.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
@@ -29,43 +29,46 @@ Boost.Python wraps (member) function pointers. Unfortunately, C++ function
pointers carry no default argument info. Take a function <tt>f</tt> with default
arguments:</p>
<code><pre>
<span class=keyword>int </span><span class=identifier>f</span><span class=special>(</span><span class=keyword>int</span><span class=special>, </span><span class=keyword>double </span><span class=special>= </span><span class=number>3.14</span><span class=special>, </span><span class=keyword>char </span><span class=keyword>const</span><span class=special>* </span><span class=special>= </span><span class=string>&quot;hello&quot;</span><span class=special>);
<span class=keyword>int </span><span class=identifier>f</span><span class=special>(</span><span class=keyword>int</span><span class=special>, </span><span class=keyword>double </span><span class=special>= </span><span class=number>3.14</span><span class=special>, </span><span class=keyword>char </span><span class=keyword>const</span><span class=special>* = </span><span class=string>&quot;hello&quot;</span><span class=special>);
</span></pre></code>
<p>
But the type of a pointer to the function <tt>f</tt> has no information
about its default arguments:</p>
<code><pre>
<span class=keyword>int</span><span class=special>(*</span><span class=identifier>g</span><span class=special>)(</span><span class=keyword>int</span><span class=special>,</span><span class=keyword>double</span><span class=special>,</span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*) </span><span class=special>= </span><span class=identifier>f</span><span class=special>; </span><span class=comment>// defaults lost!
<span class=keyword>int</span><span class=special>(*</span><span class=identifier>g</span><span class=special>)(</span><span class=keyword>int</span><span class=special>,</span><span class=keyword>double</span><span class=special>,</span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*) = </span><span class=identifier>f</span><span class=special>; // </span><span class=identifier>defaults </span><span class=identifier>lost</span><span class=special>!
</span></pre></code>
<p>
When we pass this function pointer to the <tt>def</tt> function, there is no way
to retrieve the default arguments:</p>
<code><pre>
<span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>f</span><span class=special>); </span><span class=comment>// defaults lost!
<span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>f</span><span class=special>); // </span><span class=identifier>defaults </span><span class=identifier>lost</span><span class=special>!
</span></pre></code>
<p>
Because of this, when wrapping C++ code in earlier versions of
Boost.Python, we had to resort to writing thin wrappers:</p>
Because of this, when wrapping C++ code, we had to resort to manual
wrapping as outlined in the <a href="overloading.html">
previous section</a>, or
writing thin wrappers:</p>
<code><pre>
<span class=comment>// write &quot;thin wrappers&quot;
</span><span class=keyword>int </span><span class=identifier>f1</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>x</span><span class=special>) </span><span class=special>{ </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>x</span><span class=special>); </span><span class=special>}
</span><span class=keyword>int </span><span class=identifier>f2</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>x</span><span class=special>, </span><span class=keyword>double </span><span class=identifier>y</span><span class=special>) </span><span class=special>{ </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>x</span><span class=special>,</span><span class=identifier>y</span><span class=special>); </span><span class=special>}
</span><span class=keyword>int </span><span class=identifier>f1</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>x</span><span class=special>) { </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>x</span><span class=special>); }
</span><span class=keyword>int </span><span class=identifier>f2</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>x</span><span class=special>, </span><span class=keyword>double </span><span class=identifier>y</span><span class=special>) { </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>x</span><span class=special>,</span><span class=identifier>y</span><span class=special>); }
</span><span class=comment>/*...*/
/*...*/
// in module init
</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>f</span><span class=special>); </span><span class=comment>// all arguments
</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>f2</span><span class=special>); </span><span class=comment>// two arguments
</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>f1</span><span class=special>); </span><span class=comment>// one argument
// </span><span class=identifier>in </span><span class=identifier>module </span><span class=identifier>init
</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>f</span><span class=special>); // </span><span class=identifier>all </span><span class=identifier>arguments
</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>f2</span><span class=special>); // </span><span class=identifier>two </span><span class=identifier>arguments
</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>f1</span><span class=special>); // </span><span class=identifier>one </span><span class=identifier>argument
</span></pre></code>
<p>
When you want to wrap functions (or member functions) that either:</p>
<ul><li>have default arguments, or</li><li>are overloaded with a common sequence of initial arguments</li></ul><p>
Boost.Python now has a way to make it easier.</p>
<p>
For instance, given a function:</p>
<ul><li>have default arguments, or</li><li>are overloaded with a common sequence of initial arguments</li></ul><a name="boost_python_function_overloads"></a><h2>BOOST_PYTHON_FUNCTION_OVERLOADS</h2><p>
Boost.Python now has a way to make it easier. For instance, given a function:</p>
<code><pre>
<span class=keyword>int </span><span class=identifier>foo</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>char </span><span class=identifier>b </span><span class=special>= </span><span class=number>1</span><span class=special>, </span><span class=keyword>unsigned </span><span class=identifier>c </span><span class=special>= </span><span class=number>2</span><span class=special>, </span><span class=keyword>double </span><span class=identifier>d </span><span class=special>= </span><span class=number>3</span><span class=special>);
<span class=keyword>int </span><span class=identifier>foo</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>char </span><span class=identifier>b </span><span class=special>= </span><span class=number>1</span><span class=special>, </span><span class=keyword>unsigned </span><span class=identifier>c </span><span class=special>= </span><span class=number>2</span><span class=special>, </span><span class=keyword>double </span><span class=identifier>d </span><span class=special>= </span><span class=number>3</span><span class=special>)
{
/*...*/
}
</span></pre></code>
<p>
The macro invocation:</p>
@@ -73,30 +76,67 @@ The macro invocation:</p>
<span class=identifier>BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class=special>(</span><span class=identifier>foo_overloads</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=number>1</span><span class=special>, </span><span class=number>4</span><span class=special>)
</span></pre></code>
<p>
Will automatically create the thin wrappers for us. This macro will create
will automatically create the thin wrappers for us. This macro will create
a class <tt>foo_overloads</tt> that can be passed on to <tt>def(...)</tt>. The third
and fourth macro argument are the minimum arguments and maximum arguments,
respectively. In our <tt>foo</tt> function the minimum number of arguments is 1
and the maximum number of arguments is 4. The <tt>def(...)</tt> function will
automatically add all the foo variants for us:</p>
<code><pre>
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;foo&quot;</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=identifier>foo_overloads</span><span class=special>());
<span class=identifier>def</span><span class=special>(</span><span class=string>&quot;foo&quot;</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=identifier>foo_overloads</span><span class=special>());
</span></pre></code>
<a name="boost_python_member_function_overloads"></a><h2>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</h2><p>
Objects here, objects there, objects here there everywhere. More frequently
than anything else, we need to expose member functions of our classes to
Python. Then again, we have the same inconveniences as before when default
arguments or overloads with a common sequence of initial arguments come
into play. Another macro is provided to make this a breeze.</p>
<p>
Like <tt>BOOST_PYTHON_FUNCTION_OVERLOADS</tt>,
<tt>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt> may be used to automatically create
the thin wrappers for wrapping member functions. Let's have an example:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>george
</span><span class=special>{
</span><span class=keyword>void
</span><span class=identifier>wack_em</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>int </span><span class=identifier>b </span><span class=special>= </span><span class=number>0</span><span class=special>, </span><span class=keyword>char </span><span class=identifier>c </span><span class=special>= </span><span class=literal>'x'</span><span class=special>)
{
/*...*/
}
};
</span></pre></code>
<p>
The macro invocation:</p>
<code><pre>
<span class=identifier>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class=special>(</span><span class=identifier>george_overloads</span><span class=special>, </span><span class=identifier>wack_em</span><span class=special>, </span><span class=number>1</span><span class=special>, </span><span class=number>3</span><span class=special>)
</span></pre></code>
<p>
will generate a set of thin wrappers for george's <tt>wack_em</tt> member function
accepting a minimum of 1 and a maximum of 3 arguments (i.e. the third and
fourth macro argument). The thin wrappers are all enclosed in a class named
<tt>george_overloads</tt> that can then be used as an argument to <tt>def(...)</tt>:</p>
<code><pre>
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;wack_em&quot;</span><span class=special>, &amp;</span><span class=identifier>george</span><span class=special>::</span><span class=identifier>wack_em</span><span class=special>, </span><span class=identifier>george_overloads</span><span class=special>());
</span></pre></code>
<p>
See the <a href="../../v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec">
overloads reference</a>
for details.</p>
<a name="init_and_optional"></a><h2>init and optional</h2><p>
A similar facility is provided for class constructors, again, with
default arguments or a sequence of overloads. Remember init&lt;...&gt;? For example,
default arguments or a sequence of overloads. Remember <tt>init&lt;...&gt;</tt>? For example,
given a class X with a constructor:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>X
</span><span class=special>{
</span><span class=identifier>X</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>char </span><span class=identifier>b </span><span class=special>= </span><span class=literal>'D'</span><span class=special>, </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>c </span><span class=special>= </span><span class=string>&quot;constructor&quot;</span><span class=special>, </span><span class=keyword>double </span><span class=identifier>d </span><span class=special>= </span><span class=number>0.0</span><span class=special>);
</span><span class=comment>/*...*/
</span><span class=special>}
/*...*/
}
</span></pre></code>
<p>
You can easily add this constructor to Boost.Python in one shot:</p>
<code><pre>
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>init</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>, </span><span class=identifier>optional</span><span class=special>&lt;</span><span class=keyword>char</span><span class=special>, </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>, </span><span class=keyword>double</span><span class=special>&gt; </span><span class=special>&gt;())
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>init</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>, </span><span class=identifier>optional</span><span class=special>&lt;</span><span class=keyword>char</span><span class=special>, </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>, </span><span class=keyword>double</span><span class=special>&gt; &gt;())
</span></pre></code>
<p>
Notice the use of <tt>init&lt;...&gt;</tt> and <tt>optional&lt;...&gt;</tt> to signify the default
@@ -104,12 +144,12 @@ Notice the use of <tt>init&lt;...&gt;</tt> and <tt>optional&lt;...&gt;</tt> to s
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="call_policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="object_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="30"><a href="overloading.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="auto_overloading.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -30,7 +30,7 @@ that of Python's:</p>
<ul><li>list</li><li>dict</li><li>tuple</li><li>str</li><li>long_</li><li>enum</li></ul><p>
These derived <tt>object</tt> types act like real Python types. For instance:</p>
<code><pre>
<span class=identifier>str</span><span class=special>(</span><span class=number>1</span><span class=special>) </span><span class=special>==&gt; </span><span class=string>&quot;1&quot;
<span class=identifier>str</span><span class=special>(</span><span class=number>1</span><span class=special>) ==&gt; </span><span class=string>&quot;1&quot;
</span></pre></code>
<p>
Wherever appropriate, a particular derived <tt>object</tt> has corresponding
@@ -50,11 +50,11 @@ declared below, is wrapped, it will only accept instances of Python's
<tt>str</tt> type and subtypes.</p>
<code><pre>
<span class=keyword>void </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>str </span><span class=identifier>name</span><span class=special>)
</span><span class=special>{
</span><span class=identifier>object </span><span class=identifier>n2 </span><span class=special>= </span><span class=identifier>name</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>&quot;upper&quot;</span><span class=special>)(); </span><span class=comment>// NAME = name.upper()
</span><span class=identifier>str </span><span class=identifier>NAME </span><span class=special>= </span><span class=identifier>name</span><span class=special>.</span><span class=identifier>upper</span><span class=special>(); </span><span class=comment>// better
{
</span><span class=identifier>object </span><span class=identifier>n2 </span><span class=special>= </span><span class=identifier>name</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>&quot;upper&quot;</span><span class=special>)(); // </span><span class=identifier>NAME </span><span class=special>= </span><span class=identifier>name</span><span class=special>.</span><span class=identifier>upper</span><span class=special>()
</span><span class=identifier>str </span><span class=identifier>NAME </span><span class=special>= </span><span class=identifier>name</span><span class=special>.</span><span class=identifier>upper</span><span class=special>(); // </span><span class=identifier>better
</span><span class=identifier>object </span><span class=identifier>msg </span><span class=special>= </span><span class=string>&quot;%s is bigger than %s&quot; </span><span class=special>% </span><span class=identifier>make_tuple</span><span class=special>(</span><span class=identifier>NAME</span><span class=special>,</span><span class=identifier>name</span><span class=special>);
</span><span class=special>}
}
</span></pre></code>
<p>
In finer detail:</p>
@@ -76,14 +76,14 @@ of most of Python's mutable types make copies, just as in Python.</p>
<p>
Python:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>d </span><span class=special>= </span><span class=identifier>dict</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__</span><span class=special>) </span>#<span class=identifier>copies </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>d</span><span class=special>[</span><span class=literal>'whatever'</span><span class=special>] </span>#<span class=identifier>modifies </span><span class=identifier>the </span><span class=identifier>copy
<span class=special>&gt;&gt;&gt; </span><span class=identifier>d </span><span class=special>= </span><span class=identifier>dict</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__</span><span class=special>) </span>##<span class=identifier>copies </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>d</span><span class=special>[</span><span class=literal>'whatever'</span><span class=special>] </span>##<span class=identifier>modifies </span><span class=identifier>the </span><span class=identifier>copy
</span></pre></code>
<p>
C++:</p>
<code><pre>
<span class=identifier>dict </span><span class=identifier>d</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>&quot;__dict__&quot;</span><span class=special>)); </span>#<span class=identifier>copies </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__
</span><span class=identifier>d</span><span class=special>[</span><span class=literal>'whatever'</span><span class=special>] </span><span class=special>= </span><span class=number>3</span><span class=special>; </span>#<span class=identifier>modifies </span><span class=identifier>the </span><span class=identifier>copy
<span class=identifier>dict </span><span class=identifier>d</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>&quot;__dict__&quot;</span><span class=special>)); </span>##<span class=identifier>copies </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__
</span><span class=identifier>d</span><span class=special>[</span><span class=literal>'whatever'</span><span class=special>] = </span><span class=number>3</span><span class=special>; </span>##<span class=identifier>modifies </span><span class=identifier>the </span><span class=identifier>copy
</span></pre></code>
<a name="class__lt_t_gt__as_objects"></a><h2>class_&lt;T&gt; as objects</h2><p>
Due to the dynamic nature of Boost.Python objects, any <tt>class_&lt;T&gt;</tt> may
@@ -92,13 +92,13 @@ also be one of these types! The following code snippet wraps the class
<p>
We can use this to create wrapped instances. Example:</p>
<code><pre>
<span class=identifier>object </span><span class=identifier>vec345 </span><span class=special>= </span><span class=special>(
<span class=identifier>object </span><span class=identifier>vec345 </span><span class=special>= (
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Vec2</span><span class=special>&gt;(</span><span class=string>&quot;Vec2&quot;</span><span class=special>, </span><span class=identifier>init</span><span class=special>&lt;</span><span class=keyword>double</span><span class=special>, </span><span class=keyword>double</span><span class=special>&gt;())
</span><span class=special>.</span><span class=identifier>def_readonly</span><span class=special>(</span><span class=string>&quot;length&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Point</span><span class=special>::</span><span class=identifier>length</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def_readonly</span><span class=special>(</span><span class=string>&quot;angle&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>Point</span><span class=special>::</span><span class=identifier>angle</span><span class=special>)
</span><span class=special>)(</span><span class=number>3.0</span><span class=special>, </span><span class=number>4.0</span><span class=special>);
.</span><span class=identifier>def_readonly</span><span class=special>(</span><span class=string>&quot;length&quot;</span><span class=special>, &amp;</span><span class=identifier>Point</span><span class=special>::</span><span class=identifier>length</span><span class=special>)
.</span><span class=identifier>def_readonly</span><span class=special>(</span><span class=string>&quot;angle&quot;</span><span class=special>, &amp;</span><span class=identifier>Point</span><span class=special>::</span><span class=identifier>angle</span><span class=special>)
)(</span><span class=number>3.0</span><span class=special>, </span><span class=number>4.0</span><span class=special>);
</span><span class=identifier>assert</span><span class=special>(</span><span class=identifier>vec345</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>&quot;length&quot;</span><span class=special>) </span><span class=special>== </span><span class=number>5.0</span><span class=special>);
</span><span class=identifier>assert</span><span class=special>(</span><span class=identifier>vec345</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>&quot;length&quot;</span><span class=special>) == </span><span class=number>5.0</span><span class=special>);
</span></pre></code>
<table border="0">
<tr>
@@ -108,7 +108,7 @@ We can use this to create wrapped instances. Example:</p>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -0,0 +1,83 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Deriving a Python Class</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="class_virtual_functions.html">
<link rel="next" href="virtual_functions_with_default_implementations.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Deriving a Python Class</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_virtual_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="virtual_functions_with_default_implementations.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Continuing, we can derive from our base class Base in Python and override
the virtual function in Python. Before we can do that, we have to set up
our <tt>class_</tt> wrapper as:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>, </span><span class=identifier>BaseWrap</span><span class=special>, </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>noncopyable</span><span class=special>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>)
;
</span></pre></code>
<p>
Otherwise, we have to suppress the Base class' <tt>no_init</tt> by adding an
<tt>__init__()</tt> method to all our derived classes. <tt>no_init</tt> actually adds
an <tt>__init__</tt> method that raises a Python RuntimeError exception.</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=keyword>class </span><span class=identifier>Derived</span><span class=special>(</span><span class=identifier>Base</span><span class=special>):
... </span><span class=identifier>def </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
... </span><span class=keyword>return </span><span class=number>42
</span><span class=special>...
</span></pre></code>
<p>
Cool eh? A Python class deriving from a C++ class!</p>
<p>
Let's now make an instance of our Python class <tt>Derived</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived </span><span class=special>= </span><span class=identifier>Derived</span><span class=special>()
</span></pre></code>
<p>
Calling <tt>derived.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>42
</span></pre></code>
<p>
Will yield the expected result. Finally, calling calling the free function
<tt>call_f</tt> with <tt>derived</tt> as argument:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>derived</span><span class=special>)
</span><span class=number>42
</span></pre></code>
<p>
Will also yield the expected result.</p>
<p>
Here's what's happening:</p>
<ol><li><tt>call_f(derived)</tt> is called in Python</li><li>This corresponds to <tt>def(&quot;call_f&quot;, call_f);</tt>. Boost.Python dispatches this call.</li><li><tt>int call_f(Base&amp; b) { return b.f(); }</tt> accepts the call.</li><li>The overridden virtual function <tt>f</tt> of <tt>BaseWrap</tt> is called.</li><li><tt>call_method&lt;int&gt;(self, &quot;f&quot;);</tt> dispatches the call back to Python.</li><li><tt>def f(self): return 42</tt> is finally called.</li></ol><table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_virtual_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="virtual_functions_with_default_implementations.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -0,0 +1,96 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Embedding</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="enums.html">
<link rel="next" href="using_the_interpreter.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Embedding</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="enums.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="using_the_interpreter.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
By now you should know how to use Boost.Python to call your C++ code from
Python. However, sometimes you may need to do the reverse: call Python code
from the C++-side. This requires you to <i>embed</i> the Python interpreter
into your C++ program.</p>
<p>
Currently, Boost.Python does not directly support everything you'll need
when embedding. Therefore you'll need to use the
<a href="http://www.python.org/doc/current/api/api.html">
Python/C API</a> to fill in
the gaps. However, Boost.Python already makes embedding a lot easier and,
in a future version, it may become unnecessary to touch the Python/C API at
all. So stay tuned... <img src="theme/smiley.gif"></img></p>
<a name="building_embedded_programs"></a><h2>Building embedded programs</h2><p>
To be able to use embedding in your programs, they have to be linked to
both Boost.Python's and Python's static link library.</p>
<p>
Boost.Python's static link library comes in two variants. Both are located
in Boost's <tt>/libs/python/build/bin-stage</tt> subdirectory. On Windows, the
variants are called <tt>boost_python.lib</tt> (for release builds) and
<tt>boost_python_debug.lib</tt> (for debugging). If you can't find the libraries,
you probably haven't built Boost.Python yet. See <a href="../../building.html">
Building and Testing</a> on how to do this.</p>
<p>
Python's static link library can be found in the <tt>/libs</tt> subdirectory of
your Python directory. On Windows it is called pythonXY.lib where X.Y is
your major Python version number.</p>
<p>
Additionally, Python's <tt>/include</tt> subdirectory has to be added to your
include path.</p>
<p>
In a Jamfile, all the above boils down to:</p>
<code><pre>
projectroot c:\projects\embedded_program ; # location of the program
# bring in the rules for python
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
exe embedded_program # name of the executable
: #sources
embedded_program.cpp
: # requirements
&lt;find-library&gt;boost_python &lt;library-path&gt;c:\boost\libs\python
$(PYTHON_PROPERTIES)
&lt;library-path&gt;$(PYTHON_LIB_PATH)
&lt;find-library&gt;$(PYTHON_EMBEDDED_LIBRARY) ;
</pre></code><a name="getting_started"></a><h2>Getting started</h2><p>
Being able to build is nice, but there is nothing to build yet. Embedding
the Python interpreter into one of your C++ programs requires these 4
steps:</p>
<ol><li>#include <tt>&lt;boost/python.hpp&gt;</tt><br><br></li><li>Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-652">
Py_Initialize</a>() to start the interpreter and create the <tt>__main__</tt> module.<br><br></li><li>Call other Python C API routines to use the interpreter.<br><br></li><li>Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656">
Py_Finalize</a>() to stop the interpreter and release its resources.</li></ol><p>
(Of course, there can be other C++ code between all of these steps.)</p>
<blockquote><p><i><b>Now that we can embed the interpreter in our programs, lets see how to put it to use...</b></i></p></blockquote><table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="enums.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="using_the_interpreter.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -4,7 +4,7 @@
<title>Enums</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="extracting_c___objects.html">
<link rel="next" href="iterators.html">
<link rel="next" href="embedding.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
@@ -21,7 +21,7 @@
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="extracting_c___objects.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="iterators.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="20"><a href="embedding.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
@@ -38,9 +38,9 @@ enums). To illustrate, given a C++ enum:</p>
the construct:</p>
<code><pre>
<span class=identifier>enum_</span><span class=special>&lt;</span><span class=identifier>choice</span><span class=special>&gt;(</span><span class=string>&quot;choice&quot;</span><span class=special>)
</span><span class=special>.</span><span class=identifier>value</span><span class=special>(</span><span class=string>&quot;red&quot;</span><span class=special>, </span><span class=identifier>red</span><span class=special>)
</span><span class=special>.</span><span class=identifier>value</span><span class=special>(</span><span class=string>&quot;blue&quot;</span><span class=special>, </span><span class=identifier>blue</span><span class=special>)
</span><span class=special>;
.</span><span class=identifier>value</span><span class=special>(</span><span class=string>&quot;red&quot;</span><span class=special>, </span><span class=identifier>red</span><span class=special>)
.</span><span class=identifier>value</span><span class=special>(</span><span class=string>&quot;blue&quot;</span><span class=special>, </span><span class=identifier>blue</span><span class=special>)
;
</span></pre></code>
<p>
can be used to expose to Python. The new enum type is created in the
@@ -67,26 +67,26 @@ You can access those values in Python as</p>
where my_module is the module where the enum is declared. You can also
create a new scope around a class:</p>
<code><pre>
<span class=identifier>scope </span><span class=identifier>in_X</span><span class=special>(</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>X</span><span class=special>&gt;(</span><span class=string>&quot;X&quot;</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def</span><span class=special>( </span><span class=special>... </span><span class=special>)
</span><span class=special>.</span><span class=identifier>def</span><span class=special>( </span><span class=special>... </span><span class=special>)
</span><span class=special>);
<span class=identifier>scope </span><span class=identifier>in_X </span><span class=special>= </span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>X</span><span class=special>&gt;(</span><span class=string>&quot;X&quot;</span><span class=special>)
.</span><span class=identifier>def</span><span class=special>( ... )
.</span><span class=identifier>def</span><span class=special>( ... )
;
</span><span class=comment>// Expose X::nested as X.nested
// </span><span class=identifier>Expose </span><span class=identifier>X</span><span class=special>::</span><span class=identifier>nested </span><span class=identifier>as </span><span class=identifier>X</span><span class=special>.</span><span class=identifier>nested
</span><span class=identifier>enum_</span><span class=special>&lt;</span><span class=identifier>X</span><span class=special>::</span><span class=identifier>nested</span><span class=special>&gt;(</span><span class=string>&quot;nested&quot;</span><span class=special>)
</span><span class=special>.</span><span class=identifier>value</span><span class=special>(</span><span class=string>&quot;red&quot;</span><span class=special>, </span><span class=identifier>red</span><span class=special>)
</span><span class=special>.</span><span class=identifier>value</span><span class=special>(</span><span class=string>&quot;blue&quot;</span><span class=special>, </span><span class=identifier>blue</span><span class=special>)
</span><span class=special>;
.</span><span class=identifier>value</span><span class=special>(</span><span class=string>&quot;red&quot;</span><span class=special>, </span><span class=identifier>red</span><span class=special>)
.</span><span class=identifier>value</span><span class=special>(</span><span class=string>&quot;blue&quot;</span><span class=special>, </span><span class=identifier>blue</span><span class=special>)
;
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="extracting_c___objects.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="iterators.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="20"><a href="embedding.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -4,6 +4,7 @@
<title>Exception Translation</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="iterators.html">
<link rel="next" href="general_techniques.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
@@ -20,7 +21,7 @@
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="iterators.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
<td width="20"><a href="general_techniques.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
@@ -35,23 +36,23 @@ then gives up:</p>
Users may provide custom translation. Here's an example:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>PodBayDoorException</span><span class=special>;
</span><span class=keyword>void </span><span class=identifier>translator</span><span class=special>(</span><span class=identifier>PodBayDoorException</span><span class=special>&amp; </span><span class=identifier>x</span><span class=special>) </span><span class=special>{
</span><span class=keyword>void </span><span class=identifier>translator</span><span class=special>(</span><span class=identifier>PodBayDoorException </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>x</span><span class=special>) {
</span><span class=identifier>PyErr_SetString</span><span class=special>(</span><span class=identifier>PyExc_UserWarning</span><span class=special>, </span><span class=string>&quot;I'm sorry Dave...&quot;</span><span class=special>);
</span><span class=special>}
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>kubrick</span><span class=special>) </span><span class=special>{
}
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>kubrick</span><span class=special>) {
</span><span class=identifier>register_exception_translator</span><span class=special>&lt;
</span><span class=identifier>PodBayDoorException</span><span class=special>&gt;(</span><span class=identifier>translator</span><span class=special>);
</span><span class=special>...
...
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="iterators.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
<td width="20"><a href="general_techniques.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -31,10 +31,10 @@ Consider a C++ class/struct that we want to expose to Python:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>World
</span><span class=special>{
</span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>) </span><span class=special>{ </span><span class=keyword>this</span><span class=special>-&gt;</span><span class=identifier>msg </span><span class=special>= </span><span class=identifier>msg</span><span class=special>; </span><span class=special>}
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>greet</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>msg</span><span class=special>; </span><span class=special>}
</span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>) { </span><span class=keyword>this</span><span class=special>-&gt;</span><span class=identifier>msg </span><span class=special>= </span><span class=identifier>msg</span><span class=special>; }
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>greet</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>msg</span><span class=special>; }
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>;
</span><span class=special>};
};
</span></pre></code>
<p>
We can expose this to Python by writing a corresponding Boost.Python
@@ -44,12 +44,12 @@ C++ Wrapper:</p>
</span><span class=keyword>using </span><span class=keyword>namespace </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>python</span><span class=special>;
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>hello</span><span class=special>)
</span><span class=special>{
{
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>World</span><span class=special>&gt;(</span><span class=string>&quot;World&quot;</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;greet&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>greet</span><span class=special>)
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;set&quot;</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>set</span><span class=special>)
</span><span class=special>;
</span><span class=special>}
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;greet&quot;</span><span class=special>, &amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>greet</span><span class=special>)
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;set&quot;</span><span class=special>, &amp;</span><span class=identifier>World</span><span class=special>::</span><span class=identifier>set</span><span class=special>)
;
}
</span></pre></code>
<p>
Here, we wrote a C++ class wrapper that exposes the member functions
@@ -58,8 +58,8 @@ may use our class <tt>World</tt> in Python. Here's a sample Python session:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>import </span><span class=identifier>hello
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>planet </span><span class=special>= </span><span class=identifier>hello</span><span class=special>.</span><span class=identifier>World</span><span class=special>()
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>planet</span><span class=special>.</span><span class=identifier>set</span><span class=special>(</span><span class=literal>'howdy'</span><span class=special>)
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>planet</span><span class=special>.</span><span class=identifier>greet</span><span class=special>()
&gt;&gt;&gt; </span><span class=identifier>planet</span><span class=special>.</span><span class=identifier>set</span><span class=special>(</span><span class=literal>'howdy'</span><span class=special>)
&gt;&gt;&gt; </span><span class=identifier>planet</span><span class=special>.</span><span class=identifier>greet</span><span class=special>()
</span><span class=literal>'howdy'
</span></pre></code>
<table border="0">
@@ -70,7 +70,7 @@ may use our class <tt>World</tt> in Python. Here's a sample Python session:</p>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -0,0 +1,134 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Extending Wrapped Objects in Python</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="creating_packages.html">
<link rel="next" href="reducing_compiling_time.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Extending Wrapped Objects in Python</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="creating_packages.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="reducing_compiling_time.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Thanks to Python's flexibility, you can easily add new methods to a class,
even after it was already created:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=keyword>class </span><span class=identifier>C</span><span class=special>(</span><span class=identifier>object</span><span class=special>): </span><span class=identifier>pass
</span><span class=special>&gt;&gt;&gt;
&gt;&gt;&gt; </span>##<span class=identifier>a </span><span class=identifier>regular </span><span class=identifier>function
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>def </span><span class=identifier>C_str</span><span class=special>(</span><span class=identifier>self</span><span class=special>): </span><span class=keyword>return </span><span class=literal>'A C instance!'
</span><span class=special>&gt;&gt;&gt;
&gt;&gt;&gt; </span>##<span class=identifier>now </span><span class=identifier>we </span><span class=identifier>turn </span><span class=identifier>it </span><span class=identifier>in </span><span class=identifier>a </span><span class=identifier>member </span><span class=identifier>function
</span><span class=special>&gt;&gt;&gt; </span><span class=identifier>C</span><span class=special>.</span><span class=identifier>__str__ </span><span class=special>= </span><span class=identifier>C_str
</span><span class=special>&gt;&gt;&gt;
&gt;&gt;&gt; </span><span class=identifier>c </span><span class=special>= </span><span class=identifier>C</span><span class=special>()
&gt;&gt;&gt; </span><span class=identifier>print </span><span class=identifier>c
</span><span class=identifier>A </span><span class=identifier>C </span><span class=identifier>instance</span><span class=special>!
&gt;&gt;&gt; </span><span class=identifier>C_str</span><span class=special>(</span><span class=identifier>c</span><span class=special>)
</span><span class=identifier>A </span><span class=identifier>C </span><span class=identifier>instance</span><span class=special>!
</span></pre></code>
<p>
Yes, Python rox. <img src="theme/smiley.gif"></img></p>
<p>
We can do the same with classes that were wrapped with Boost.Python. Suppose
we have a class <tt>point</tt> in C++:</p>
<code><pre>
<span class=keyword>class </span><span class=identifier>point </span><span class=special>{...};
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>_geom</span><span class=special>)
{
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>point</span><span class=special>&gt;(</span><span class=string>&quot;point&quot;</span><span class=special>)...;
}
</span></pre></code>
<p>
If we are using the technique from the previous session, <a href="creating_packages.html">
Creating Packages</a>, we can code directly into <tt>geom/__init__.py</tt>:</p>
<code><pre>
<span class=identifier>from </span><span class=identifier>_geom </span><span class=identifier>import </span><span class=special>*
</span>##<span class=identifier>a </span><span class=identifier>regular </span><span class=identifier>function
</span><span class=identifier>def </span><span class=identifier>point_str</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
</span><span class=keyword>return </span><span class=identifier>str</span><span class=special>((</span><span class=identifier>self</span><span class=special>.</span><span class=identifier>x</span><span class=special>, </span><span class=identifier>self</span><span class=special>.</span><span class=identifier>y</span><span class=special>))
</span>##<span class=identifier>now </span><span class=identifier>we </span><span class=identifier>turn </span><span class=identifier>it </span><span class=identifier>into </span><span class=identifier>a </span><span class=identifier>member </span><span class=identifier>function
</span><span class=identifier>point</span><span class=special>.</span><span class=identifier>__str__ </span><span class=special>= </span><span class=identifier>point_str
</span></pre></code>
<p>
<b>All</b> point instances created from C++ will also have this member function!
This technique has several advantages:</p>
<ul><li>Cut down compile times to zero for these additional functions</li><li>Reduce the memory footprint to virtually zero</li><li>Minimize the need to recompile</li><li>Rapid prototyping (you can move the code to C++ if required without changing the interface)</li></ul><p>
You can even add a little syntactic sugar with the use of metaclasses. Let's
create a special metaclass that &quot;injects&quot; methods in other classes.</p>
<code><pre>
##<span class=identifier>The </span><span class=identifier>one </span><span class=identifier>Boost</span><span class=special>.</span><span class=identifier>Python </span><span class=identifier>uses </span><span class=keyword>for </span><span class=identifier>all </span><span class=identifier>wrapped </span><span class=identifier>classes</span><span class=special>.
</span>##<span class=identifier>You </span><span class=identifier>can </span><span class=identifier>use </span><span class=identifier>here </span><span class=identifier>any </span><span class=keyword>class </span><span class=identifier>exported </span><span class=identifier>by </span><span class=identifier>Boost </span><span class=identifier>instead </span><span class=identifier>of </span><span class=string>&quot;point&quot;
</span><span class=identifier>BoostPythonMetaclass </span><span class=special>= </span><span class=identifier>point</span><span class=special>.</span><span class=identifier>__class__
</span><span class=keyword>class </span><span class=identifier>injector</span><span class=special>(</span><span class=identifier>object</span><span class=special>):
</span><span class=keyword>class </span><span class=identifier>__metaclass__</span><span class=special>(</span><span class=identifier>BoostPythonMetaclass</span><span class=special>):
</span><span class=identifier>def </span><span class=identifier>__init__</span><span class=special>(</span><span class=identifier>self</span><span class=special>, </span><span class=identifier>name</span><span class=special>, </span><span class=identifier>bases</span><span class=special>, </span><span class=identifier>dict</span><span class=special>):
</span><span class=keyword>for </span><span class=identifier>b </span><span class=identifier>in </span><span class=identifier>bases</span><span class=special>:
</span><span class=keyword>if </span><span class=identifier>type</span><span class=special>(</span><span class=identifier>b</span><span class=special>) </span><span class=keyword>not </span><span class=identifier>in </span><span class=special>(</span><span class=identifier>self</span><span class=special>, </span><span class=identifier>type</span><span class=special>):
</span><span class=keyword>for </span><span class=identifier>k</span><span class=special>,</span><span class=identifier>v </span><span class=identifier>in </span><span class=identifier>dict</span><span class=special>.</span><span class=identifier>items</span><span class=special>():
</span><span class=identifier>setattr</span><span class=special>(</span><span class=identifier>b</span><span class=special>,</span><span class=identifier>k</span><span class=special>,</span><span class=identifier>v</span><span class=special>)
</span><span class=keyword>return </span><span class=identifier>type</span><span class=special>.</span><span class=identifier>__init__</span><span class=special>(</span><span class=identifier>self</span><span class=special>, </span><span class=identifier>name</span><span class=special>, </span><span class=identifier>bases</span><span class=special>, </span><span class=identifier>dict</span><span class=special>)
</span>##<span class=identifier>inject </span><span class=identifier>some </span><span class=identifier>methods </span><span class=identifier>in </span><span class=identifier>the </span><span class=identifier>point </span><span class=identifier>foo
</span><span class=keyword>class </span><span class=identifier>more_point</span><span class=special>(</span><span class=identifier>injector</span><span class=special>, </span><span class=identifier>point</span><span class=special>):
</span><span class=identifier>def </span><span class=identifier>__repr__</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
</span><span class=keyword>return </span><span class=literal>'Point(x=%s, y=%s)' </span><span class=special>% (</span><span class=identifier>self</span><span class=special>.</span><span class=identifier>x</span><span class=special>, </span><span class=identifier>self</span><span class=special>.</span><span class=identifier>y</span><span class=special>)
</span><span class=identifier>def </span><span class=identifier>foo</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
</span><span class=identifier>print </span><span class=literal>'foo!'
</span></pre></code>
<p>
Now let's see how it got:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>print </span><span class=identifier>point</span><span class=special>()
</span><span class=identifier>Point</span><span class=special>(</span><span class=identifier>x</span><span class=special>=</span><span class=number>10</span><span class=special>, </span><span class=identifier>y</span><span class=special>=</span><span class=number>10</span><span class=special>)
&gt;&gt;&gt; </span><span class=identifier>point</span><span class=special>().</span><span class=identifier>foo</span><span class=special>()
</span><span class=identifier>foo</span><span class=special>!
</span></pre></code>
<p>
Another useful idea is to replace constructors with factory functions:</p>
<code><pre>
<span class=identifier>_point </span><span class=special>= </span><span class=identifier>point
</span><span class=identifier>def </span><span class=identifier>point</span><span class=special>(</span><span class=identifier>x</span><span class=special>=</span><span class=number>0</span><span class=special>, </span><span class=identifier>y</span><span class=special>=</span><span class=number>0</span><span class=special>):
</span><span class=keyword>return </span><span class=identifier>_point</span><span class=special>(</span><span class=identifier>x</span><span class=special>, </span><span class=identifier>y</span><span class=special>)
</span></pre></code>
<p>
In this simple case there is not much gained, but for constructurs with
many overloads and/or arguments this is often a great simplification, again
with virtually zero memory footprint and zero compile-time overhead for
the keyword support.</p>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="creating_packages.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="reducing_compiling_time.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -28,7 +28,7 @@
At some point, we will need to get C++ values out of object instances. This
can be achieved with the <tt>extract&lt;T&gt;</tt> function. Consider the following:</p>
<code><pre>
<span class=keyword>double </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>o</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>&quot;length&quot;</span><span class=special>); </span><span class=comment>// compile error
<span class=keyword>double </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>o</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>&quot;length&quot;</span><span class=special>); // </span><span class=identifier>compile </span><span class=identifier>error
</span></pre></code>
<p>
In the code above, we got a compiler error because Boost.Python
@@ -52,15 +52,15 @@ appropriate exception is thrown. To avoid an exception, we need to
test for extractibility:</p>
<code><pre>
<span class=identifier>extract</span><span class=special>&lt;</span><span class=identifier>Vec2</span><span class=special>&amp;&gt; </span><span class=identifier>x</span><span class=special>(</span><span class=identifier>o</span><span class=special>);
</span><span class=keyword>if </span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>check</span><span class=special>()) </span><span class=special>{
</span><span class=identifier>Vec2</span><span class=special>&amp; </span><span class=identifier>v </span><span class=special>= </span><span class=identifier>x</span><span class=special>(); </span><span class=special>...
</span><span class=keyword>if </span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>check</span><span class=special>()) {
</span><span class=identifier>Vec2</span><span class=special>&amp; </span><span class=identifier>v </span><span class=special>= </span><span class=identifier>x</span><span class=special>(); ...
</span></pre></code>
<p>
<img src="theme/bulb.gif"></img> The astute reader might have noticed that the <tt>extract&lt;T&gt;</tt>
facility in fact solves the mutable copying problem:</p>
<code><pre>
<span class=identifier>dict </span><span class=identifier>d </span><span class=special>= </span><span class=identifier>extract</span><span class=special>&lt;</span><span class=identifier>dict</span><span class=special>&gt;(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>&quot;__dict__&quot;</span><span class=special>));
</span><span class=identifier>d</span><span class=special>[</span><span class=literal>'whatever'</span><span class=special>] </span><span class=special>= </span><span class=number>3</span><span class=special>; </span>#<span class=identifier>modifies </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__ </span><span class=special>!
</span><span class=identifier>d</span><span class=special>[</span><span class=literal>'whatever'</span><span class=special>] = </span><span class=number>3</span><span class=special>; </span>##<span class=identifier>modifies </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__ </span><span class=special>!
</span></pre></code>
<table border="0">
<tr>
@@ -70,7 +70,7 @@ facility in fact solves the mutable copying problem:</p>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -64,7 +64,7 @@ But before you do, you might want to fire up Python 2.2 or later and type
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -0,0 +1,43 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>General Techniques</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="exception_translation.html">
<link rel="next" href="creating_packages.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>General Techniques</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="exception_translation.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="creating_packages.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Here are presented some useful techniques that you can use while wrapping code with Boost.Python.</p>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="exception_translation.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="creating_packages.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -33,7 +33,7 @@ abstract base classes.</p>
<p>
Consider this trivial inheritance structure:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>Base </span><span class=special>{ </span><span class=keyword>virtual </span><span class=special>~</span><span class=identifier>Base</span><span class=special>(); </span><span class=special>};
<span class=keyword>struct </span><span class=identifier>Base </span><span class=special>{ </span><span class=keyword>virtual </span><span class=special>~</span><span class=identifier>Base</span><span class=special>(); };
</span><span class=keyword>struct </span><span class=identifier>Derived </span><span class=special>: </span><span class=identifier>Base </span><span class=special>{};
</span></pre></code>
<p>
@@ -42,22 +42,22 @@ instances:</p>
<code><pre>
<span class=keyword>void </span><span class=identifier>b</span><span class=special>(</span><span class=identifier>Base</span><span class=special>*);
</span><span class=keyword>void </span><span class=identifier>d</span><span class=special>(</span><span class=identifier>Derived</span><span class=special>*);
</span><span class=identifier>Base</span><span class=special>* </span><span class=identifier>factory</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=keyword>new </span><span class=identifier>Derived</span><span class=special>; </span><span class=special>}
</span><span class=identifier>Base</span><span class=special>* </span><span class=identifier>factory</span><span class=special>() { </span><span class=keyword>return </span><span class=keyword>new </span><span class=identifier>Derived</span><span class=special>; }
</span></pre></code>
<p>
We've seen how we can wrap the base class <tt>Base</tt>:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>)
</span><span class=comment>/*...*/
</span><span class=special>;
/*...*/
;
</span></pre></code>
<p>
Now we can inform Boost.Python of the inheritance relationship between
<tt>Derived</tt> and its base class <tt>Base</tt>. Thus:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Derived</span><span class=special>, </span><span class=identifier>bases</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>&gt; </span><span class=special>&gt;(</span><span class=string>&quot;Derived&quot;</span><span class=special>)
</span><span class=comment>/*...*/
</span><span class=special>;
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Derived</span><span class=special>, </span><span class=identifier>bases</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>&gt; &gt;(</span><span class=string>&quot;Derived&quot;</span><span class=special>)
/*...*/
;
</span></pre></code>
<p>
Doing so, we get some things for free:</p>
@@ -89,7 +89,7 @@ call policies</a> later.</p>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -3,7 +3,7 @@
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Iterators</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="enums.html">
<link rel="prev" href="using_the_interpreter.html">
<link rel="next" href="exception_translation.html">
</head>
<body>
@@ -20,7 +20,7 @@
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="enums.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="30"><a href="using_the_interpreter.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="exception_translation.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
@@ -34,12 +34,12 @@ iterators, but these are two very different beasts.</p>
<ul><li>1 category (forward)</li><li>1 operation category (next())</li><li>Raises StopIteration exception at end</li></ul><p>
The typical Python iteration protocol: <tt><b>for y in x...</b></tt> is as follows:</p>
<code><pre>
<span class=identifier>iter </span><span class=special>= </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__iter__</span><span class=special>() </span>#<span class=identifier>get </span><span class=identifier>iterator
<span class=identifier>iter </span><span class=special>= </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__iter__</span><span class=special>() </span>##<span class=identifier>get </span><span class=identifier>iterator
</span><span class=keyword>try</span><span class=special>:
</span><span class=keyword>while </span><span class=number>1</span><span class=special>:
</span><span class=identifier>y </span><span class=special>= </span><span class=identifier>iter</span><span class=special>.</span><span class=identifier>next</span><span class=special>() </span>#<span class=identifier>get </span><span class=identifier>each </span><span class=identifier>item
</span><span class=special>... </span>#<span class=identifier>process </span><span class=identifier>y
</span><span class=identifier>except </span><span class=identifier>StopIteration</span><span class=special>: </span><span class=identifier>pass </span>#<span class=identifier>iterator </span><span class=identifier>exhausted
</span><span class=identifier>y </span><span class=special>= </span><span class=identifier>iter</span><span class=special>.</span><span class=identifier>next</span><span class=special>() </span>##<span class=identifier>get </span><span class=identifier>each </span><span class=identifier>item
</span><span class=special>... </span>##<span class=identifier>process </span><span class=identifier>y
</span><span class=identifier>except </span><span class=identifier>StopIteration</span><span class=special>: </span><span class=identifier>pass </span>##<span class=identifier>iterator </span><span class=identifier>exhausted
</span></pre></code>
<p>
Boost.Python provides some mechanisms to make C++ iterators play along
@@ -47,14 +47,14 @@ nicely as Python iterators. What we need to do is to produce
appropriate __iter__ function from C++ iterators that is compatible
with the Python iteration protocol. For example:</p>
<code><pre>
<span class=identifier>object </span><span class=identifier>get_iterator </span><span class=special>= </span><span class=identifier>iterator</span><span class=special>&lt;</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt; </span><span class=special>&gt;();
<span class=identifier>object </span><span class=identifier>get_iterator </span><span class=special>= </span><span class=identifier>iterator</span><span class=special>&lt;</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt; &gt;();
</span><span class=identifier>object </span><span class=identifier>iter </span><span class=special>= </span><span class=identifier>get_iterator</span><span class=special>(</span><span class=identifier>v</span><span class=special>);
</span><span class=identifier>object </span><span class=identifier>first </span><span class=special>= </span><span class=identifier>iter</span><span class=special>.</span><span class=identifier>next</span><span class=special>();
</span></pre></code>
<p>
Or for use in class_&lt;&gt;:</p>
<code><pre>
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;__iter__&quot;</span><span class=special>, </span><span class=identifier>iterator</span><span class=special>&lt;</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt; </span><span class=special>&gt;())
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;__iter__&quot;</span><span class=special>, </span><span class=identifier>iterator</span><span class=special>&lt;</span><span class=identifier>vector</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt; &gt;())
</span></pre></code>
<p>
<b>range</b></p>
@@ -81,18 +81,18 @@ bogon Particle accelerator code:</p>
Now, our C++ Wrapper:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>F</span><span class=special>&gt;(</span><span class=string>&quot;Field&quot;</span><span class=special>)
</span><span class=special>.</span><span class=identifier>property</span><span class=special>(</span><span class=string>&quot;pions&quot;</span><span class=special>, </span><span class=identifier>range</span><span class=special>(&amp;</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>p_begin</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>p_end</span><span class=special>))
</span><span class=special>.</span><span class=identifier>property</span><span class=special>(</span><span class=string>&quot;bogons&quot;</span><span class=special>, </span><span class=identifier>range</span><span class=special>(&amp;</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>b_begin</span><span class=special>, </span><span class=special>&amp;</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>b_end</span><span class=special>));
.</span><span class=identifier>property</span><span class=special>(</span><span class=string>&quot;pions&quot;</span><span class=special>, </span><span class=identifier>range</span><span class=special>(&amp;</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>p_begin</span><span class=special>, &amp;</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>p_end</span><span class=special>))
.</span><span class=identifier>property</span><span class=special>(</span><span class=string>&quot;bogons&quot;</span><span class=special>, </span><span class=identifier>range</span><span class=special>(&amp;</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>b_begin</span><span class=special>, &amp;</span><span class=identifier>F</span><span class=special>::</span><span class=identifier>b_end</span><span class=special>));
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="enums.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="30"><a href="using_the_interpreter.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="exception_translation.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -3,7 +3,7 @@
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Object Interface</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="default_arguments.html">
<link rel="prev" href="auto_overloading.html">
<link rel="next" href="basic_interface.html">
</head>
<body>
@@ -20,7 +20,7 @@
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="default_arguments.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="30"><a href="auto_overloading.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="basic_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
@@ -40,12 +40,12 @@ should minimize the learning curve significantly.</p>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="default_arguments.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="30"><a href="auto_overloading.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="basic_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -0,0 +1,88 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Overloading</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="call_policies.html">
<link rel="next" href="default_arguments.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Overloading</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="call_policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="default_arguments.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
The following illustrates a scheme for manually wrapping an overloaded
member functions. Of course, the same technique can be applied to wrapping
overloaded non-member functions.</p>
<p>
We have here our C++ class:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>X
</span><span class=special>{
</span><span class=keyword>bool </span><span class=identifier>f</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>a</span><span class=special>)
{
</span><span class=keyword>return </span><span class=keyword>true</span><span class=special>;
}
</span><span class=keyword>bool </span><span class=identifier>f</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>double </span><span class=identifier>b</span><span class=special>)
{
</span><span class=keyword>return </span><span class=keyword>true</span><span class=special>;
}
</span><span class=keyword>bool </span><span class=identifier>f</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>double </span><span class=identifier>b</span><span class=special>, </span><span class=keyword>char </span><span class=identifier>c</span><span class=special>)
{
</span><span class=keyword>return </span><span class=keyword>true</span><span class=special>;
}
</span><span class=keyword>int </span><span class=identifier>f</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>int </span><span class=identifier>b</span><span class=special>, </span><span class=keyword>int </span><span class=identifier>c</span><span class=special>)
{
</span><span class=keyword>return </span><span class=identifier>a </span><span class=special>+ </span><span class=identifier>b </span><span class=special>+ </span><span class=identifier>c</span><span class=special>;
};
};
</span></pre></code>
<p>
Class X has 4 overloaded functions. We shall start by introducing some
member function pointer variables:</p>
<code><pre>
<span class=keyword>bool </span><span class=special>(</span><span class=identifier>X</span><span class=special>::*</span><span class=identifier>fx1</span><span class=special>)(</span><span class=keyword>int</span><span class=special>) = &amp;</span><span class=identifier>X</span><span class=special>::</span><span class=identifier>f</span><span class=special>;
</span><span class=keyword>bool </span><span class=special>(</span><span class=identifier>X</span><span class=special>::*</span><span class=identifier>fx2</span><span class=special>)(</span><span class=keyword>int</span><span class=special>, </span><span class=keyword>double</span><span class=special>) = &amp;</span><span class=identifier>X</span><span class=special>::</span><span class=identifier>f</span><span class=special>;
</span><span class=keyword>bool </span><span class=special>(</span><span class=identifier>X</span><span class=special>::*</span><span class=identifier>fx3</span><span class=special>)(</span><span class=keyword>int</span><span class=special>, </span><span class=keyword>double</span><span class=special>, </span><span class=keyword>char</span><span class=special>)= &amp;</span><span class=identifier>X</span><span class=special>::</span><span class=identifier>f</span><span class=special>;
</span><span class=keyword>int </span><span class=special>(</span><span class=identifier>X</span><span class=special>::*</span><span class=identifier>fx4</span><span class=special>)(</span><span class=keyword>int</span><span class=special>, </span><span class=keyword>int</span><span class=special>, </span><span class=keyword>int</span><span class=special>) = &amp;</span><span class=identifier>X</span><span class=special>::</span><span class=identifier>f</span><span class=special>;
</span></pre></code>
<p>
With these in hand, we can proceed to define and wrap this for Python:</p>
<code><pre>
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>fx1</span><span class=special>)
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>fx2</span><span class=special>)
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>fx3</span><span class=special>)
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>fx4</span><span class=special>)
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="call_policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="default_arguments.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -39,9 +39,9 @@ Following C/C++ tradition, let's start with the &quot;hello, world&quot;. A C++
Function:</p>
<code><pre>
<span class=keyword>char </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>greet</span><span class=special>()
</span><span class=special>{
{
</span><span class=keyword>return </span><span class=string>&quot;hello, world&quot;</span><span class=special>;
</span><span class=special>}
}
</span></pre></code>
<p>
can be exposed to Python by writing a Boost.Python wrapper:</p>
@@ -50,9 +50,9 @@ can be exposed to Python by writing a Boost.Python wrapper:</p>
</span><span class=keyword>using </span><span class=keyword>namespace </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>python</span><span class=special>;
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>hello</span><span class=special>)
</span><span class=special>{
{
</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;greet&quot;</span><span class=special>, </span><span class=identifier>greet</span><span class=special>);
</span><span class=special>}
}
</span></pre></code>
<p>
That's it. We're done. We can now build this as a shared library. The
@@ -70,7 +70,7 @@ resulting DLL is now visible to Python. Here's a sample Python session:</p>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -62,6 +62,11 @@ with every boost distribution: [*bjam].
Besides bjam, there are of course other ways to get your module built.
What's written here should not be taken as "the one and only way".
There are of course other build tools apart from [^bjam].
Take note however that the preferred build tool for Boost.Python is bjam.
There are so many ways to set up the build incorrectly. Experience shows
that 90% of the "I can't build Boost.Python" problems come from people
who had to use a different tool.
]
We shall skip over the details. Our objective will be to simply create the
@@ -339,9 +344,10 @@ Our C++ [^Var] class and its data members can be exposed to Python:
.def_readonly("name", &Var::name)
.def_readwrite("value", &Var::value);
Then, in Python:
Then, in Python, assuming we have placed our Var class inside the namespace
hello as we did before:
>>> x = Var('pi')
>>> x = hello.Var('pi')
>>> x.value = 3.14
>>> print x.name, 'is around', x.value
pi is around 3.14
@@ -378,8 +384,8 @@ attributes can just be a different syntax for a method call. Wrapping our
[^Num] class using Boost.Python:
class_<Num>("Num")
.add_property("rovalue", &Var::get)
.add_property("value", &Var::get, &Var::set);
.add_property("rovalue", &Num::get)
.add_property("value", &Num::get, &Num::set);
And at last, in Python:
@@ -392,7 +398,7 @@ And at last, in Python:
Take note that the class property [^rovalue] is exposed as [*read-only]
since the [^rovalue] setter member function is not passed in:
.add_property("rovalue", &Var::get)
.add_property("rovalue", &Num::get)
[page:1 Inheritance]
@@ -520,15 +526,24 @@ available, since Base is an abstract class.
In Python, let us try to instantiate our [^Base] class:
>>> base = Base()
AttributeError: ...
RuntimeError: This class cannot be instantiated from Python
Why is it an error? [^Base] is an abstract class. As such it is advisable
to define the Python wrapper with [^no_init] as we have done above. Doing
so will disallow abstract base classes such as [^Base] to be instantiated.
[h2 Deriving a Python class]
[page:1 Deriving a Python Class]
Now, at last, we can even derive from our base class [^Base] in Python:
Continuing, we can derive from our base class Base in Python and override
the virtual function in Python. Before we can do that, we have to set up
our [^class_] wrapper as:
class_<Base, BaseWrap, boost::noncopyable>("Base")
;
Otherwise, we have to suppress the Base class' [^no_init] by adding an
[^__init__()] method to all our derived classes. [^no_init] actually adds
an [^__init__] method that raises a Python RuntimeError exception.
>>> class Derived(Base):
... def f(self):
@@ -563,30 +578,45 @@ Here's what's happening:
# [^call_method<int>(self, "f");] dispatches the call back to Python.
# [^def f(self): return 42] is finally called.
Rewind back to our [^Base] class, if its member function [^f] was not
declared as pure virtual:
[page:1 Virtual Functions with Default Implementations]
Recall that in the [@class_virtual_functions.html previous section], we
wrapped a class with a pure virtual function that we then implemented in
C++ or Python classes derived from it. Our base class:
struct Base
{
virtual int f() = 0;
};
had a pure virtual function [^f]. If, however, its member function [^f] was
not declared as pure virtual:
struct Base
{
virtual int f() { return 0; }
};
And instead is implemented to return [^0], as shown above.
and instead had a default implementation that returns [^0], as shown above,
we need to add a forwarding function that calls the [^Base] default virtual
function [^f] implementation:
struct BaseWrap : Base
{
BaseWrap(PyObject* self_)
: self(self_) {}
int f() { return call_method<int>(self, "f"); }
static int default_f(Base* b) { return b->Base::f(); } // <<=== added
int default_f() { return Base::f(); } // <<=== ***ADDED***
PyObject* self;
};
then, our Boost.Python wrapper:
Then, Boost.Python needs to keep track of 1) the dispatch function [^f] and
2) the forwarding function to its default implementation [^default_f].
There's a special [^def] function for this purpose. Here's how it is
applied to our example above:
class_<Base, BaseWrap>("Base")
.def("f", &BaseWrap::default_f)
;
.def("f", &Base::f, &BaseWrap::default_f)
Note that we are allowing [^Base] objects to be instantiated this time,
unlike before where we specifically defined the [^class_<Base>] with
@@ -649,7 +679,7 @@ and intuitively:
.def(self + int()) // __add__
.def(int() + self) // __radd__
.def(self - self) // __sub__
.def(self - int()) // __rsub__
.def(self - int()) // __sub__
.def(self += int()) // __iadd__
.def(self -= other<int>())
.def(self < self); // __lt__
@@ -865,6 +895,52 @@ these can be found [@../../v2/reference.html#models_of_call_policies here].
"Explicit is better than implicit"[br]
"In the face of ambiguity, refuse the temptation to guess"[br]]
[page:1 Overloading]
The following illustrates a scheme for manually wrapping an overloaded
member functions. Of course, the same technique can be applied to wrapping
overloaded non-member functions.
We have here our C++ class:
struct X
{
bool f(int a)
{
return true;
}
bool f(int a, double b)
{
return true;
}
bool f(int a, double b, char c)
{
return true;
}
int f(int a, int b, int c)
{
return a + b + c;
};
};
Class X has 4 overloaded functions. We shall start by introducing some
member function pointer variables:
bool (X::*fx1)(int) = &X::f;
bool (X::*fx2)(int, double) = &X::f;
bool (X::*fx3)(int, double, char)= &X::f;
int (X::*fx4)(int, int, int) = &X::f;
With these in hand, we can proceed to define and wrap this for Python:
.def("f", fx1)
.def("f", fx2)
.def("f", fx3)
.def("f", fx4)
[page:1 Default Arguments]
Boost.Python wraps (member) function pointers. Unfortunately, C++ function
@@ -883,8 +959,9 @@ to retrieve the default arguments:
def("f", f); // defaults lost!
Because of this, when wrapping C++ code in earlier versions of
Boost.Python, we had to resort to writing thin wrappers:
Because of this, when wrapping C++ code, we had to resort to manual
wrapping as outlined in the [@overloading.html previous section], or
writing thin wrappers:
// write "thin wrappers"
int f1(int x) { f(x); }
@@ -902,27 +979,67 @@ When you want to wrap functions (or member functions) that either:
* have default arguments, or
* are overloaded with a common sequence of initial arguments
Boost.Python now has a way to make it easier.
[h2 BOOST_PYTHON_FUNCTION_OVERLOADS]
For instance, given a function:
Boost.Python now has a way to make it easier. For instance, given a function:
int foo(int a, char b = 1, unsigned c = 2, double d = 3);
int foo(int a, char b = 1, unsigned c = 2, double d = 3)
{
/*...*/
}
The macro invocation:
BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 1, 4)
Will automatically create the thin wrappers for us. This macro will create
will automatically create the thin wrappers for us. This macro will create
a class [^foo_overloads] that can be passed on to [^def(...)]. The third
and fourth macro argument are the minimum arguments and maximum arguments,
respectively. In our [^foo] function the minimum number of arguments is 1
and the maximum number of arguments is 4. The [^def(...)] function will
automatically add all the foo variants for us:
.def("foo", foo, foo_overloads());
def("foo", foo, foo_overloads());
[h2 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS]
Objects here, objects there, objects here there everywhere. More frequently
than anything else, we need to expose member functions of our classes to
Python. Then again, we have the same inconveniences as before when default
arguments or overloads with a common sequence of initial arguments come
into play. Another macro is provided to make this a breeze.
Like [^BOOST_PYTHON_FUNCTION_OVERLOADS],
[^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] may be used to automatically create
the thin wrappers for wrapping member functions. Let's have an example:
struct george
{
void
wack_em(int a, int b = 0, char c = 'x')
{
/*...*/
}
};
The macro invocation:
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(george_overloads, wack_em, 1, 3)
will generate a set of thin wrappers for george's [^wack_em] member function
accepting a minimum of 1 and a maximum of 3 arguments (i.e. the third and
fourth macro argument). The thin wrappers are all enclosed in a class named
[^george_overloads] that can then be used as an argument to [^def(...)]:
.def("wack_em", &george::wack_em, george_overloads());
See the [@../../v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec overloads reference]
for details.
[h2 init and optional]
A similar facility is provided for class constructors, again, with
default arguments or a sequence of overloads. Remember init<...>? For example,
default arguments or a sequence of overloads. Remember [^init<...>]? For example,
given a class X with a constructor:
struct X
@@ -938,6 +1055,73 @@ You can easily add this constructor to Boost.Python in one shot:
Notice the use of [^init<...>] and [^optional<...>] to signify the default
(optional arguments).
[page:1 Auto-Overloading]
It was mentioned in passing in the previous section that
[^BOOST_PYTHON_FUNCTION_OVERLOADS] and [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS]
can also be used for overloaded functions and member functions with a
common sequence of initial arguments. Here is an example:
void foo()
{
/*...*/
}
void foo(bool a)
{
/*...*/
}
void foo(bool a, int b)
{
/*...*/
}
void foo(bool a, int b, char c)
{
/*...*/
}
Like in the previous section, we can generate thin wrappers for these
overloaded functions in one-shot:
BOOST_PYTHON_FUNCTION_OVERLOADS(foo_overloads, foo, 0, 3)
Then...
.def("foo", foo, foo_overloads());
Notice though that we have a situation now where we have a minimum of zero
(0) arguments and a maximum of 3 arguments.
[h2 Manual Wrapping]
It is important to emphasize however that [*the overloaded functions must
have a common sequence of initial arguments]. Otherwise, our scheme above
will not work. If this is not the case, we have to wrap our functions
[@overloading.html manually].
Actually, we can mix and match manual wrapping of overloaded functions and
automatic wrapping through [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] and
its sister, [^BOOST_PYTHON_FUNCTION_OVERLOADS]. Following up on our example
presented in the section [@overloading.html on overloading], since the
first 4 overload functins have a common sequence of initial arguments, we
can use [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] to automatically wrap the
first three of the [^def]s and manually wrap just the last. Here's
how we'll do this:
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4)
Create a member function pointers as above for both X::f overloads:
bool (X::*fx1)(int, double, char) = &X::f;
int (X::*fx2)(int, int, int) = &X::f;
Then...
.def("f", fx1, xf_overloads());
.def("f", fx2)
[page Object Interface]
Python is dynamically typed, unlike C++ which is statically typed. Python
@@ -1140,10 +1324,10 @@ You can access those values in Python as
where my_module is the module where the enum is declared. You can also
create a new scope around a class:
scope in_X(class_<X>("X")
scope in_X = class_<X>("X")
.def( ... )
.def( ... )
);
;
// Expose X::nested as X.nested
enum_<X::nested>("nested")
@@ -1151,6 +1335,258 @@ create a new scope around a class:
.value("blue", blue)
;
[def Py_Initialize [@http://www.python.org/doc/current/api/initialization.html#l2h-652 Py_Initialize]]
[def Py_Finalize [@http://www.python.org/doc/current/api/initialization.html#l2h-656 Py_Finalize]]
[def PyRun_String [@http://www.python.org/doc/current/api/veryhigh.html#l2h-55 PyRun_String]]
[def PyRun_File [@http://www.python.org/doc/current/api/veryhigh.html#l2h-56 PyRun_File]]
[def Py_eval_input [@http://www.python.org/doc/current/api/veryhigh.html#l2h-58 Py_eval_input]]
[def Py_file_input [@http://www.python.org/doc/current/api/veryhigh.html#l2h-59 Py_file_input]]
[def Py_single_input [@http://www.python.org/doc/current/api/veryhigh.html#l2h-60 Py_single_input]]
[def Py_XINCREF [@http://www.python.org/doc/current/api/countingRefs.html#l2h-65 Py_XINCREF]]
[def Py_XDECREF [@http://www.python.org/doc/current/api/countingRefs.html#l2h-67 Py_XDECREF]]
[def PyImport_AppendInittab [@http://www.python.org/doc/current/api/importing.html#l2h-137 PyImport_AppendInittab]]
[def PyImport_AddModule [@http://www.python.org/doc/current/api/importing.html#l2h-125 PyImport_AddModule]]
[def PyModule_New [@http://www.python.org/doc/current/api/moduleObjects.html#l2h-591 PyModule_New]]
[def PyModule_GetDict [@http://www.python.org/doc/current/api/moduleObjects.html#l2h-594 PyModule_GetDict]]
[page:0 Embedding]
By now you should know how to use Boost.Python to call your C++ code from
Python. However, sometimes you may need to do the reverse: call Python code
from the C++-side. This requires you to ['embed] the Python interpreter
into your C++ program.
Currently, Boost.Python does not directly support everything you'll need
when embedding. Therefore you'll need to use the
[@http://www.python.org/doc/current/api/api.html Python/C API] to fill in
the gaps. However, Boost.Python already makes embedding a lot easier and,
in a future version, it may become unnecessary to touch the Python/C API at
all. So stay tuned... :-)
[h2 Building embedded programs]
To be able to use embedding in your programs, they have to be linked to
both Boost.Python's and Python's static link library.
Boost.Python's static link library comes in two variants. Both are located
in Boost's [^/libs/python/build/bin-stage] subdirectory. On Windows, the
variants are called [^boost_python.lib] (for release builds) and
[^boost_python_debug.lib] (for debugging). If you can't find the libraries,
you probably haven't built Boost.Python yet. See [@../../building.html
Building and Testing] on how to do this.
Python's static link library can be found in the [^/libs] subdirectory of
your Python directory. On Windows it is called pythonXY.lib where X.Y is
your major Python version number.
Additionally, Python's [^/include] subdirectory has to be added to your
include path.
In a Jamfile, all the above boils down to:
[pre
projectroot c:\projects\embedded_program ; # location of the program
# bring in the rules for python
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
include python.jam ;
exe embedded_program # name of the executable
: #sources
embedded_program.cpp
: # requirements
<find-library>boost_python <library-path>c:\boost\libs\python
$(PYTHON_PROPERTIES)
<library-path>$(PYTHON_LIB_PATH)
<find-library>$(PYTHON_EMBEDDED_LIBRARY) ;
]
[h2 Getting started]
Being able to build is nice, but there is nothing to build yet. Embedding
the Python interpreter into one of your C++ programs requires these 4
steps:
# '''#include''' [^<boost/python.hpp>][br][br]
# Call Py_Initialize() to start the interpreter and create the [^__main__] module.[br][br]
# Call other Python C API routines to use the interpreter.[br][br]
# Call Py_Finalize() to stop the interpreter and release its resources.
(Of course, there can be other C++ code between all of these steps.)
[:['[*Now that we can embed the interpreter in our programs, lets see how to put it to use...]]]
[page:1 Using the interpreter]
As you probably already know, objects in Python are reference-counted.
Naturally, the [^PyObject]s of the Python/C API are also reference-counted.
There is a difference however. While the reference-counting is fully
automatic in Python, the Python/C API requires you to do it
[@http://www.python.org/doc/current/api/refcounts.html by hand]. This is
messy and especially hard to get right in the presence of C++ exceptions.
Fortunately Boost.Python provides the [@../../v2/handle.html handle] class
template to automate the process.
[h2 Reference-counting handles]
There are two ways in which a function in the Python/C API can return a
[^PyObject*]: as a ['borrowed reference] or as a ['new reference]. Which of
these a function uses, is listed in that function's documentation. The two
require slightely different approaches to reference-counting but both can
be 'handled' by Boost.Python.
For a function returning a ['borrowed reference] we'll have to tell the
[^handle] that the [^PyObject*] is borrowed with the aptly named
[@../../v2/handle.html#borrowed-spec borrowed] function. Two functions
returning borrowed references are PyImport_AddModule and PyModule_GetDict.
The former returns a reference to an already imported module, the latter
retrieves a module's namespace dictionary. Let's use them to retrieve the
namespace of the [^__main__] module:
handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
handle<> main_namespace(borrowed( PyModule_GetDict(main_module.get()) ));
Because the Python/C API doesn't know anything about [^handle]s, we used
the [@../../v2/handle.html#handle-spec-observers get] member function to
retrieve the [^PyObject*] from which the [^handle] was constructed.
For a function returning a ['new reference] we can just create a [^handle]
out of the raw [^PyObject*] without wrapping it in a call to borrowed. One
such function that returns a new reference is PyRun_String which we'll
discuss in the next section.
[blurb __detail__ [*Handle is a class ['template], so why haven't we been using any template parameters?][br]
[br]
[^handle] has a single template parameter specifying the type of the managed object. This type is [^PyObject] 99% of the time, so the parameter was defaulted to [^PyObject] for convenience. Therefore we can use the shorthand [^handle<>] instead of the longer, but equivalent, [^handle<PyObject>].
]
[h2 Running Python code]
To run Python code from C++ there is a family of functions in the API
starting with the PyRun prefix. You can find the full list of these
functions [@http://www.python.org/doc/current/api/veryhigh.html here]. They
all work similarly so we will look at only one of them, namely:
PyObject* PyRun_String(char *str, int start, PyObject *globals, PyObject *locals)
PyRun_String takes the code to execute as a null-terminated (C-style)
string in its [^str] parameter. The function returns a new reference to a
Python object. Which object is returned depends on the [^start] paramater.
The [^start] parameter is the start symbol from the Python grammar to use
for interpreting the code. The possible values are:
[table Start symbols
[Py_eval_input] [for interpreting isolated expressions]
[Py_file_input] [for interpreting sequences of statements]
[Py_single_input] [for interpreting a single statement]
]
When using Py_eval_input, the input string must contain a single expression
and its result is returned. When using Py_file_input, the string can
contain an abitrary number of statements and None is returned.
Py_single_input works in the same way as Py_file_input but only accepts a
single statement.
Lastly, the [^globals] and [^locals] parameters are Python dictionaries
containing the globals and locals of the context in which to run the code.
For most intents and purposes you can use the namespace dictionary of the
[^__main__] module for both parameters.
We have already seen how to get the [^__main__] module's namespace so let's
run some Python code in it:
handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
handle<> main_namespace(borrowed( PyModule_GetDict(main_module.get()) ));
handle<>( PyRun_String("hello = file('hello.txt', 'w')\n"
"hello.write('Hello world!')\n"
"hello.close()", Py_file_input,
main_namespace.get(), main_namespace.get()) );
This should create a file called 'hello.txt' in the current directory
containing a phrase that is well-known in programming circles.
__note__ [*Note] that we wrap the return value of PyRun_String in a
(nameless) [^handle] even though we are not interested in it. If we didn't
do this, the the returned object would be kept alive unnecessarily. Unless
you want to be a Dr. Frankenstein, always wrap [^PyObject*]s in [^handle]s.
[h2 Beyond handles]
It's nice that [^handle] manages the reference counting details for us, but
other than that it doesn't do much. Often we'd like to have a more useful
class to manipulate Python objects. But we have already seen such a class
in the [@object_interface.html previous section]: the aptly named [^object]
class and it's derivatives. What we haven't seen, is that they can be
constructed from a [^handle]. The following examples should illustrate this
fact:
handle<> main_module(borrowed( PyImport_AddModule("__main__") ));
dict main_namespace(handle<>(borrowed( PyModule_GetDict(main_module.get()) )));
handle<>( PyRun_String("result = 5 ** 2", Py_file_input,
main_namespace.ptr(), main_namespace.ptr()) );
int five_squared = extract<int>( main_namespace["result"] );
Here we create a dictionary object for the [^__main__] module's namespace.
Then we assign 5 squared to the result variable and read this variable from
the dictionary. Another way to achieve the same result is to let
PyRun_String return the result directly with Py_eval_input:
object result(handle<>( PyRun_String("5 ** 2", Py_eval_input,
main_namespace.ptr(), main_namespace.ptr()) ));
int five_squared = extract<int>(result);
__note__ [*Note] that [^object]'s member function to return the wrapped
[^PyObject*] is called [^ptr] instead of [^get]. This makes sense if you
take into account the different functions that [^object] and [^handle]
perform.
[h2 Exception handling]
If an exception occurs in the execution of some Python code, the PyRun_String function returns a null pointer. Constructing a [^handle] out of this null pointer throws [@../../v2/errors.html#error_already_set-spec error_already_set], so basically, the Python exception is automatically translated into a C++ exception when using [^handle]:
try
{
object result(handle<>( PyRun_String("5/0", Py_eval_input,
main_namespace.ptr(), main_namespace.ptr()) ));
// execution will never get here:
int five_divided_by_zero = extract<int>(result);
}
catch(error_already_set)
{
// handle the exception in some way
}
The [^error_already_set] exception class doesn't carry any information in itself. To find out more about the Python exception that occurred, you need to use the [@http://www.python.org/doc/api/exceptionHandling.html exception handling functions] of the Python/C API in your catch-statement. This can be as simple as calling [@http://www.python.org/doc/api/exceptionHandling.html#l2h-70 PyErr_Print()] to print the exception's traceback to the console, or comparing the type of the exception with those of the [@http://www.python.org/doc/api/standardExceptions.html standard exceptions]:
catch(error_already_set)
{
if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError))
{
// handle ZeroDivisionError specially
}
else
{
// print all other errors to stderr
PyErr_Print();
}
}
(To retrieve even more information from the exception you can use some of the other exception handling functions listed [@http://www.python.org/doc/api/exceptionHandling.html here].)
If you'd rather not have [^handle] throw a C++ exception when it is constructed, you can use the [@../../v2/handle.html#allow_null-spec allow_null] function in the same way you'd use borrowed:
handle<> result(allow_null( PyRun_String("5/0", Py_eval_input,
main_namespace.ptr(), main_namespace.ptr()) ));
if (!result)
// Python exception occurred
else
// everything went okay, it's safe to use the result
[page Iterators]
In C++, and STL in particular, we see iterators everywhere. Python also has
@@ -1237,7 +1673,7 @@ then gives up:
Users may provide custom translation. Here's an example:
struct PodBayDoorException;
void translator(PodBayDoorException& x) {
void translator(PodBayDoorException const& x) {
PyErr_SetString(PyExc_UserWarning, "I'm sorry Dave...");
}
BOOST_PYTHON_MODULE(kubrick) {
@@ -1245,3 +1681,321 @@ Users may provide custom translation. Here's an example:
PodBayDoorException>(translator);
...
[page General Techniques]
Here are presented some useful techniques that you can use while wrapping code with Boost.Python.
[page:1 Creating Packages]
A Python package is a collection of modules that provide to the user a certain
functionality. If you're not familiar on how to create packages, a good
introduction to them is provided in the
[@http://www.python.org/doc/current/tut/node8.html Python Tutorial].
But we are wrapping C++ code, using Boost.Python. How can we provide a nice
package interface to our users? To better explain some concepts, let's work
with an example.
We have a C++ library that works with sounds: reading and writing various
formats, applying filters to the sound data, etc. It is named (conveniently)
[^sounds]. Our library already has a neat C++ namespace hierarchy, like so:
sounds::core
sounds::io
sounds::filters
We would like to present this same hierarchy to the Python user, allowing him
to write code like this:
import sounds.filters
sounds.filters.echo(...) # echo is a C++ function
The first step is to write the wrapping code. We have to export each module
separately with Boost.Python, like this:
/* file core.cpp */
BOOST_PYTHON_MODULE(core)
{
/* export everything in the sounds::core namespace */
...
}
/* file io.cpp */
BOOST_PYTHON_MODULE(io)
{
/* export everything in the sounds::io namespace */
...
}
/* file filters.cpp */
BOOST_PYTHON_MODULE(filters)
{
/* export everything in the sounds::filters namespace */
...
}
Compiling these files will generate the following Python extensions:
[^core.pyd], [^io.pyd] and [^filters.pyd].
[blurb __note__ The extension [^.pyd] is used for python extension modules, which
are just shared libraries. Using the default for your system, like [^.so] for
Unix and [^.dll] for Windows, works just as well.]
Now, we create this directory structure for our Python package:
[pre
sounds/
__init__.py
core.pyd
filters.pyd
io.pyd
]
The file [^__init__.py] is what tells Python that the directory [^sounds/] is
actually a Python package. It can be a empty file, but can also perform some
magic, that will be shown later.
Now our package is ready. All the user has to do is put [^sounds] into his
[@http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000 PYTHONPATH] and fire up the interpreter:
>>> import sounds.io
>>> import sounds.filters
>>> sound = sounds.io.open('file.mp3')
>>> new_sound = sounds.filters.echo(sound, 1.0)
Nice heh?
This is the simplest way to create hierarchies of packages, but it is not very
flexible. What if we want to add a ['pure] Python function to the filters
package, for instance, one that applies 3 filters in a sound object at once?
Sure, you can do this in C++ and export it, but why not do so in Python? You
don't have to recompile the extension modules, plus it will be easier to write
it.
If we want this flexibility, we will have to complicate our package hierarchy a
little. First, we will have to change the name of the extension modules:
/* file core.cpp */
BOOST_PYTHON_MODULE(_core)
{
...
/* export everything in the sounds::core namespace */
}
Note that we added an underscore to the module name. The filename will have to
be changed to [^_core.pyd] as well, and we do the same to the other extension modules.
Now, we change our package hierarchy like so:
[pre
sounds/
__init__.py
core/
__init__.py
_core.pyd
filters/
__init__.py
_filters.pyd
io/
__init__.py
_io.pyd
]
Note that we created a directory for each extension module, and added a
__init__.py to each one. But if we leave it that way, the user will have to
access the functions in the core module with this syntax:
>>> import sounds.core._core
>>> sounds.core._core.foo(...)
which is not what we want. But here enters the [^__init__.py] magic: everything
that is brought to the [^__init__.py] namespace can be accessed directly by the
user. So, all we have to do is bring the entire namespace from [^_core.pyd]
to [^core/__init__.py]. So add this line of code to [^sounds/core/__init__.py]:
from _core import *
We do the same for the other packages. Now the user accesses the functions and
classes in the extension modules like before:
>>> import sounds.filters
>>> sounds.filters.echo(...)
with the additional benefit that we can easily add pure Python functions to
any module, in a way that the user can't tell the difference between a C++
function and a Python function. Let's add a ['pure] Python function,
[^echo_noise], to the [^filters] package. This function applies both the
[^echo] and [^noise] filters in sequence in the given [^sound] object. We
create a file named [^sounds/filters/echo_noise.py] and code our function:
import _filters
def echo_noise(sound):
s = _filters.echo(sound)
s = _filters.noise(sound)
return s
Next, we add this line to [^sounds/filters/__init__.py]:
from echo_noise import echo_noise
And that's it. The user now accesses this function like any other function
from the [^filters] package:
>>> import sounds.filters
>>> sounds.filters.echo_noise(...)
[page:1 Extending Wrapped Objects in Python]
Thanks to Python's flexibility, you can easily add new methods to a class,
even after it was already created:
>>> class C(object): pass
>>>
>>> # a regular function
>>> def C_str(self): return 'A C instance!'
>>>
>>> # now we turn it in a member function
>>> C.__str__ = C_str
>>>
>>> c = C()
>>> print c
A C instance!
>>> C_str(c)
A C instance!
Yes, Python rox. :-)
We can do the same with classes that were wrapped with Boost.Python. Suppose
we have a class [^point] in C++:
class point {...};
BOOST_PYTHON_MODULE(_geom)
{
class_<point>("point")...;
}
If we are using the technique from the previous session, [@creating_packages.html
Creating Packages], we can code directly into [^geom/__init__.py]:
from _geom import *
# a regular function
def point_str(self):
return str((self.x, self.y))
# now we turn it into a member function
point.__str__ = point_str
[*All] point instances created from C++ will also have this member function!
This technique has several advantages:
* Cut down compile times to zero for these additional functions
* Reduce the memory footprint to virtually zero
* Minimize the need to recompile
* Rapid prototyping (you can move the code to C++ if required without changing the interface)
You can even add a little syntactic sugar with the use of metaclasses. Let's
create a special metaclass that "injects" methods in other classes.
# The one Boost.Python uses for all wrapped classes.
# You can use here any class exported by Boost instead of "point"
BoostPythonMetaclass = point.__class__
class injector(object):
class __metaclass__(BoostPythonMetaclass):
def __init__(self, name, bases, dict):
for b in bases:
if type(b) not in (self, type):
for k,v in dict.items():
setattr(b,k,v)
return type.__init__(self, name, bases, dict)
# inject some methods in the point foo
class more_point(injector, point):
def __repr__(self):
return 'Point(x=%s, y=%s)' % (self.x, self.y)
def foo(self):
print 'foo!'
Now let's see how it got:
>>> print point()
Point(x=10, y=10)
>>> point().foo()
foo!
Another useful idea is to replace constructors with factory functions:
_point = point
def point(x=0, y=0):
return _point(x, y)
In this simple case there is not much gained, but for constructurs with
many overloads and/or arguments this is often a great simplification, again
with virtually zero memory footprint and zero compile-time overhead for
the keyword support.
[page:1 Reducing Compiling Time]
If you have ever exported a lot of classes, you know that it takes quite a good
time to compile the Boost.Python wrappers. Plus the memory consumption can
easily become too high. If this is causing you problems, you can split the
class_ definitions in multiple files:
/* file point.cpp */
#include <point.h>
#include <boost/python.hpp>
void export_point()
{
class_<point>("point")...;
}
/* file triangle.cpp */
#include <triangle.h>
#include <boost/python.hpp>
void export_triangle()
{
class_<triangle>("triangle")...;
}
Now you create a file [^main.cpp], which contains the [^BOOST_PYTHON_MODULE]
macro, and call the various export functions inside it.
void export_point();
void export_triangle();
BOOST_PYTHON_MODULE(_geom)
{
export_point();
export_triangle();
}
Compiling and linking together all this files produces the same result as the
usual approach:
#include <boost/python.hpp>
#include <point.h>
#include <triangle.h>
BOOST_PYTHON_MODULE(_geom)
{
class_<point>("point")...;
class_<triangle>("triangle")...;
}
but the memory is kept under control.
This method is recommended too if you are developing the C++ library and
exporting it to Python at the same time: changes in a class will only demand
the compilation of a single cpp, instead of the entire wrapper code.
[blurb __note__ If you're exporting your classes with [@../../../pyste/index.html Pyste],
take a look at the [^--multiple] option, that generates the wrappers in
various files as demonstrated here.]
[blurb __note__ This method is useful too if you are getting the error message
['"fatal error C1204:Compiler limit:internal structure overflow"] when compiling
a large source file, as explained in the [@../../v2/faq.html#c1204 FAQ].]

View File

@@ -0,0 +1,115 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Reducing Compiling Time</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="extending_wrapped_objects_in_python.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Reducing Compiling Time</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="extending_wrapped_objects_in_python.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
</tr>
</table>
<p>
If you have ever exported a lot of classes, you know that it takes quite a good
time to compile the Boost.Python wrappers. Plus the memory consumption can
easily become too high. If this is causing you problems, you can split the
class_ definitions in multiple files:</p>
<code><pre>
<span class=comment>/* file point.cpp */
</span><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>point</span><span class=special>.</span><span class=identifier>h</span><span class=special>&gt;
</span><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>python</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;
</span><span class=keyword>void </span><span class=identifier>export_point</span><span class=special>()
{
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>point</span><span class=special>&gt;(</span><span class=string>&quot;point&quot;</span><span class=special>)...;
}
/* </span><span class=identifier>file </span><span class=identifier>triangle</span><span class=special>.</span><span class=identifier>cpp </span><span class=special>*/
</span><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>triangle</span><span class=special>.</span><span class=identifier>h</span><span class=special>&gt;
</span><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>python</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;
</span><span class=keyword>void </span><span class=identifier>export_triangle</span><span class=special>()
{
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>triangle</span><span class=special>&gt;(</span><span class=string>&quot;triangle&quot;</span><span class=special>)...;
}
</span></pre></code>
<p>
Now you create a file <tt>main.cpp</tt>, which contains the <tt>BOOST_PYTHON_MODULE</tt>
macro, and call the various export functions inside it. </p>
<code><pre>
<span class=keyword>void </span><span class=identifier>export_point</span><span class=special>();
</span><span class=keyword>void </span><span class=identifier>export_triangle</span><span class=special>();
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>_geom</span><span class=special>)
{
</span><span class=identifier>export_point</span><span class=special>();
</span><span class=identifier>export_triangle</span><span class=special>();
}
</span></pre></code>
<p>
Compiling and linking together all this files produces the same result as the
usual approach:</p>
<code><pre>
<span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>python</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;
</span><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>point</span><span class=special>.</span><span class=identifier>h</span><span class=special>&gt;
</span><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>triangle</span><span class=special>.</span><span class=identifier>h</span><span class=special>&gt;
</span><span class=identifier>BOOST_PYTHON_MODULE</span><span class=special>(</span><span class=identifier>_geom</span><span class=special>)
{
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>point</span><span class=special>&gt;(</span><span class=string>&quot;point&quot;</span><span class=special>)...;
</span><span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>triangle</span><span class=special>&gt;(</span><span class=string>&quot;triangle&quot;</span><span class=special>)...;
}
</span></pre></code>
<p>
but the memory is kept under control. </p>
<p>
This method is recommended too if you are developing the C++ library and
exporting it to Python at the same time: changes in a class will only demand
the compilation of a single cpp, instead of the entire wrapper code.</p>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img> If you're exporting your classes with <a href="../../../pyste/index.html">
Pyste</a>,
take a look at the <tt>--multiple</tt> option, that generates the wrappers in
various files as demonstrated here. </td>
</tr>
</table>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/note.gif"></img> This method is useful too if you are getting the error message
<i>&quot;fatal error C1204:Compiler limit:internal structure overflow&quot;</i> when compiling
a large source file, as explained in the <a href="../../v2/faq.html#c1204">
FAQ</a>. </td>
</tr>
</table>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="extending_wrapped_objects_in_python.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -0,0 +1,236 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Using the interpreter</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="embedding.html">
<link rel="next" href="iterators.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Using the interpreter</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="embedding.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="iterators.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
As you probably already know, objects in Python are reference-counted.
Naturally, the <tt>PyObject</tt>s of the Python/C API are also reference-counted.
There is a difference however. While the reference-counting is fully
automatic in Python, the Python/C API requires you to do it
<a href="http://www.python.org/doc/current/api/refcounts.html">
by hand</a>. This is
messy and especially hard to get right in the presence of C++ exceptions.
Fortunately Boost.Python provides the <a href="../../v2/handle.html">
handle</a> class
template to automate the process.</p>
<a name="reference_counting_handles"></a><h2>Reference-counting handles</h2><p>
There are two ways in which a function in the Python/C API can return a
<tt>PyObject*</tt>: as a <i>borrowed reference</i> or as a <i>new reference</i>. Which of
these a function uses, is listed in that function's documentation. The two
require slightely different approaches to reference-counting but both can
be 'handled' by Boost.Python.</p>
<p>
For a function returning a <i>borrowed reference</i> we'll have to tell the
<tt>handle</tt> that the <tt>PyObject*</tt> is borrowed with the aptly named
<a href="../../v2/handle.html#borrowed-spec">
borrowed</a> function. Two functions
returning borrowed references are <a href="http://www.python.org/doc/current/api/importing.html#l2h-125">
PyImport_AddModule</a> and <a href="http://www.python.org/doc/current/api/moduleObjects.html#l2h-594">
PyModule_GetDict</a>.
The former returns a reference to an already imported module, the latter
retrieves a module's namespace dictionary. Let's use them to retrieve the
namespace of the <tt>__main__</tt> module:</p>
<code><pre>
<span class=identifier>handle</span><span class=special>&lt;&gt; </span><span class=identifier>main_module</span><span class=special>(</span><span class=identifier>borrowed</span><span class=special>( </span><span class=identifier>PyImport_AddModule</span><span class=special>(</span><span class=string>&quot;__main__&quot;</span><span class=special>) ));
</span><span class=identifier>handle</span><span class=special>&lt;&gt; </span><span class=identifier>main_namespace</span><span class=special>(</span><span class=identifier>borrowed</span><span class=special>( </span><span class=identifier>PyModule_GetDict</span><span class=special>(</span><span class=identifier>main_module</span><span class=special>.</span><span class=identifier>get</span><span class=special>()) ));
</span></pre></code>
<p>
Because the Python/C API doesn't know anything about <tt>handle</tt>s, we used
the <a href="../../v2/handle.html#handle-spec-observers">
get</a> member function to
retrieve the <tt>PyObject*</tt> from which the <tt>handle</tt> was constructed.</p>
<p>
For a function returning a <i>new reference</i> we can just create a <tt>handle</tt>
out of the raw <tt>PyObject*</tt> without wrapping it in a call to borrowed. One
such function that returns a new reference is <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55">
PyRun_String</a> which we'll
discuss in the next section.</p>
<table width="80%" border="0" align="center">
<tr>
<td class="note_box">
<img src="theme/lens.gif"></img> <b>Handle is a class <i>template</i>, so why haven't we been using any template parameters?</b><br>
<br>
<tt>handle</tt> has a single template parameter specifying the type of the managed object. This type is <tt>PyObject</tt> 99% of the time, so the parameter was defaulted to <tt>PyObject</tt> for convenience. Therefore we can use the shorthand <tt>handle&lt;&gt;</tt> instead of the longer, but equivalent, <tt>handle&lt;PyObject&gt;</tt>.
</td>
</tr>
</table>
<a name="running_python_code"></a><h2>Running Python code</h2><p>
To run Python code from C++ there is a family of functions in the API
starting with the PyRun prefix. You can find the full list of these
functions <a href="http://www.python.org/doc/current/api/veryhigh.html">
here</a>. They
all work similarly so we will look at only one of them, namely:</p>
<code><pre>
<span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>PyRun_String</span><span class=special>(</span><span class=keyword>char </span><span class=special>*</span><span class=identifier>str</span><span class=special>, </span><span class=keyword>int </span><span class=identifier>start</span><span class=special>, </span><span class=identifier>PyObject </span><span class=special>*</span><span class=identifier>globals</span><span class=special>, </span><span class=identifier>PyObject </span><span class=special>*</span><span class=identifier>locals</span><span class=special>)
</span></pre></code>
<p>
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55">
PyRun_String</a> takes the code to execute as a null-terminated (C-style)
string in its <tt>str</tt> parameter. The function returns a new reference to a
Python object. Which object is returned depends on the <tt>start</tt> paramater.</p>
<p>
The <tt>start</tt> parameter is the start symbol from the Python grammar to use
for interpreting the code. The possible values are:</p>
<table width="90%" border="0" align="center"> <tr>
<td class="table_title" colspan="6">
Start symbols </td>
</tr>
<tr><tr><td class="table_cells"><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58">
Py_eval_input</a></td><td class="table_cells">for interpreting isolated expressions</td></tr><td class="table_cells"><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59">
Py_file_input</a></td><td class="table_cells">for interpreting sequences of statements</td></tr><td class="table_cells"><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-60">
Py_single_input</a></td><td class="table_cells">for interpreting a single statement</td></tr></table>
<p>
When using <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58">
Py_eval_input</a>, the input string must contain a single expression
and its result is returned. When using <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59">
Py_file_input</a>, the string can
contain an abitrary number of statements and None is returned.
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-60">
Py_single_input</a> works in the same way as <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59">
Py_file_input</a> but only accepts a
single statement.</p>
<p>
Lastly, the <tt>globals</tt> and <tt>locals</tt> parameters are Python dictionaries
containing the globals and locals of the context in which to run the code.
For most intents and purposes you can use the namespace dictionary of the
<tt>__main__</tt> module for both parameters.</p>
<p>
We have already seen how to get the <tt>__main__</tt> module's namespace so let's
run some Python code in it:</p>
<code><pre>
<span class=identifier>handle</span><span class=special>&lt;&gt; </span><span class=identifier>main_module</span><span class=special>(</span><span class=identifier>borrowed</span><span class=special>( </span><span class=identifier>PyImport_AddModule</span><span class=special>(</span><span class=string>&quot;__main__&quot;</span><span class=special>) ));
</span><span class=identifier>handle</span><span class=special>&lt;&gt; </span><span class=identifier>main_namespace</span><span class=special>(</span><span class=identifier>borrowed</span><span class=special>( </span><span class=identifier>PyModule_GetDict</span><span class=special>(</span><span class=identifier>main_module</span><span class=special>.</span><span class=identifier>get</span><span class=special>()) ));
</span><span class=identifier>handle</span><span class=special>&lt;&gt;( </span><span class=identifier>PyRun_String</span><span class=special>(</span><span class=string>&quot;hello = file('hello.txt', 'w')\n&quot;
</span><span class=string>&quot;hello.write('Hello world!')\n&quot;
</span><span class=string>&quot;hello.close()&quot;</span><span class=special>, </span><span class=identifier>Py_file_input</span><span class=special>,
</span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>get</span><span class=special>(), </span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>get</span><span class=special>()) );
</span></pre></code>
<p>
This should create a file called 'hello.txt' in the current directory
containing a phrase that is well-known in programming circles.</p>
<p>
<img src="theme/note.gif"></img> <b>Note</b> that we wrap the return value of <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55">
PyRun_String</a> in a
(nameless) <tt>handle</tt> even though we are not interested in it. If we didn't
do this, the the returned object would be kept alive unnecessarily. Unless
you want to be a Dr. Frankenstein, always wrap <tt>PyObject*</tt>s in <tt>handle</tt>s.</p>
<a name="beyond_handles"></a><h2>Beyond handles</h2><p>
It's nice that <tt>handle</tt> manages the reference counting details for us, but
other than that it doesn't do much. Often we'd like to have a more useful
class to manipulate Python objects. But we have already seen such a class
in the <a href="object_interface.html">
previous section</a>: the aptly named <tt>object</tt>
class and it's derivatives. What we haven't seen, is that they can be
constructed from a <tt>handle</tt>. The following examples should illustrate this
fact:</p>
<code><pre>
<span class=identifier>handle</span><span class=special>&lt;&gt; </span><span class=identifier>main_module</span><span class=special>(</span><span class=identifier>borrowed</span><span class=special>( </span><span class=identifier>PyImport_AddModule</span><span class=special>(</span><span class=string>&quot;__main__&quot;</span><span class=special>) ));
</span><span class=identifier>dict </span><span class=identifier>main_namespace</span><span class=special>(</span><span class=identifier>handle</span><span class=special>&lt;&gt;(</span><span class=identifier>borrowed</span><span class=special>( </span><span class=identifier>PyModule_GetDict</span><span class=special>(</span><span class=identifier>main_module</span><span class=special>.</span><span class=identifier>get</span><span class=special>()) )));
</span><span class=identifier>handle</span><span class=special>&lt;&gt;( </span><span class=identifier>PyRun_String</span><span class=special>(</span><span class=string>&quot;result = 5 ** 2&quot;</span><span class=special>, </span><span class=identifier>Py_file_input</span><span class=special>,
</span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>ptr</span><span class=special>(), </span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>ptr</span><span class=special>()) );
</span><span class=keyword>int </span><span class=identifier>five_squared </span><span class=special>= </span><span class=identifier>extract</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;( </span><span class=identifier>main_namespace</span><span class=special>[</span><span class=string>&quot;result&quot;</span><span class=special>] );
</span></pre></code>
<p>
Here we create a dictionary object for the <tt>__main__</tt> module's namespace.
Then we assign 5 squared to the result variable and read this variable from
the dictionary. Another way to achieve the same result is to let
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55">
PyRun_String</a> return the result directly with <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58">
Py_eval_input</a>:</p>
<code><pre>
<span class=identifier>object </span><span class=identifier>result</span><span class=special>(</span><span class=identifier>handle</span><span class=special>&lt;&gt;( </span><span class=identifier>PyRun_String</span><span class=special>(</span><span class=string>&quot;5 ** 2&quot;</span><span class=special>, </span><span class=identifier>Py_eval_input</span><span class=special>,
</span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>ptr</span><span class=special>(), </span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>ptr</span><span class=special>()) ));
</span><span class=keyword>int </span><span class=identifier>five_squared </span><span class=special>= </span><span class=identifier>extract</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;(</span><span class=identifier>result</span><span class=special>);
</span></pre></code>
<p>
<img src="theme/note.gif"></img> <b>Note</b> that <tt>object</tt>'s member function to return the wrapped
<tt>PyObject*</tt> is called <tt>ptr</tt> instead of <tt>get</tt>. This makes sense if you
take into account the different functions that <tt>object</tt> and <tt>handle</tt>
perform.</p>
<a name="exception_handling"></a><h2>Exception handling</h2><p>
If an exception occurs in the execution of some Python code, the <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55">
PyRun_String</a> function returns a null pointer. Constructing a <tt>handle</tt> out of this null pointer throws <a href="../../v2/errors.html#error_already_set-spec">
error_already_set</a>, so basically, the Python exception is automatically translated into a C++ exception when using <tt>handle</tt>:</p>
<code><pre>
<span class=keyword>try
</span><span class=special>{
</span><span class=identifier>object </span><span class=identifier>result</span><span class=special>(</span><span class=identifier>handle</span><span class=special>&lt;&gt;( </span><span class=identifier>PyRun_String</span><span class=special>(</span><span class=string>&quot;5/0&quot;</span><span class=special>, </span><span class=identifier>Py_eval_input</span><span class=special>,
</span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>ptr</span><span class=special>(), </span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>ptr</span><span class=special>()) ));
// </span><span class=identifier>execution </span><span class=identifier>will </span><span class=identifier>never </span><span class=identifier>get </span><span class=identifier>here</span><span class=special>:
</span><span class=keyword>int </span><span class=identifier>five_divided_by_zero </span><span class=special>= </span><span class=identifier>extract</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;(</span><span class=identifier>result</span><span class=special>);
}
</span><span class=keyword>catch</span><span class=special>(</span><span class=identifier>error_already_set</span><span class=special>)
{
// </span><span class=identifier>handle </span><span class=identifier>the </span><span class=identifier>exception </span><span class=identifier>in </span><span class=identifier>some </span><span class=identifier>way
</span><span class=special>}
</span></pre></code>
<p>
The <tt>error_already_set</tt> exception class doesn't carry any information in itself. To find out more about the Python exception that occurred, you need to use the <a href="http://www.python.org/doc/api/exceptionHandling.html">
exception handling functions</a> of the Python/C API in your catch-statement. This can be as simple as calling <a href="http://www.python.org/doc/api/exceptionHandling.html#l2h-70">
PyErr_Print()</a> to print the exception's traceback to the console, or comparing the type of the exception with those of the <a href="http://www.python.org/doc/api/standardExceptions.html">
standard exceptions</a>:</p>
<code><pre>
<span class=keyword>catch</span><span class=special>(</span><span class=identifier>error_already_set</span><span class=special>)
{
</span><span class=keyword>if </span><span class=special>(</span><span class=identifier>PyErr_ExceptionMatches</span><span class=special>(</span><span class=identifier>PyExc_ZeroDivisionError</span><span class=special>))
{
// </span><span class=identifier>handle </span><span class=identifier>ZeroDivisionError </span><span class=identifier>specially
</span><span class=special>}
</span><span class=keyword>else
</span><span class=special>{
// </span><span class=identifier>print </span><span class=identifier>all </span><span class=identifier>other </span><span class=identifier>errors </span><span class=identifier>to </span><span class=identifier>stderr
</span><span class=identifier>PyErr_Print</span><span class=special>();
}
}
</span></pre></code>
<p>
(To retrieve even more information from the exception you can use some of the other exception handling functions listed <a href="http://www.python.org/doc/api/exceptionHandling.html">
here</a>.)</p>
<p>
If you'd rather not have <tt>handle</tt> throw a C++ exception when it is constructed, you can use the <a href="../../v2/handle.html#allow_null-spec">
allow_null</a> function in the same way you'd use borrowed:</p>
<code><pre>
<span class=identifier>handle</span><span class=special>&lt;&gt; </span><span class=identifier>result</span><span class=special>(</span><span class=identifier>allow_null</span><span class=special>( </span><span class=identifier>PyRun_String</span><span class=special>(</span><span class=string>&quot;5/0&quot;</span><span class=special>, </span><span class=identifier>Py_eval_input</span><span class=special>,
</span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>ptr</span><span class=special>(), </span><span class=identifier>main_namespace</span><span class=special>.</span><span class=identifier>ptr</span><span class=special>()) ));
</span><span class=keyword>if </span><span class=special>(!</span><span class=identifier>result</span><span class=special>)
// </span><span class=identifier>Python </span><span class=identifier>exception </span><span class=identifier>occurred
</span><span class=keyword>else
</span><span class=comment>// everything went okay, it's safe to use the result
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="embedding.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="iterators.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -0,0 +1,122 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Virtual Functions with Default Implementations</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="deriving_a_python_class.html">
<link rel="next" href="class_operators_special_functions.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Virtual Functions with Default Implementations</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="deriving_a_python_class.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_operators_special_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Recall that in the <a href="class_virtual_functions.html">
previous section</a>, we
wrapped a class with a pure virtual function that we then implemented in
C++ or Python classes derived from it. Our base class:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>Base
</span><span class=special>{
</span><span class=keyword>virtual </span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() = </span><span class=number>0</span><span class=special>;
};
</span></pre></code>
<p>
had a pure virtual function <tt>f</tt>. If, however, its member function <tt>f</tt> was
not declared as pure virtual:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>Base
</span><span class=special>{
</span><span class=keyword>virtual </span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() { </span><span class=keyword>return </span><span class=number>0</span><span class=special>; }
};
</span></pre></code>
<p>
and instead had a default implementation that returns <tt>0</tt>, as shown above,
we need to add a forwarding function that calls the <tt>Base</tt> default virtual
function <tt>f</tt> implementation:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>BaseWrap </span><span class=special>: </span><span class=identifier>Base
</span><span class=special>{
</span><span class=identifier>BaseWrap</span><span class=special>(</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self_</span><span class=special>)
: </span><span class=identifier>self</span><span class=special>(</span><span class=identifier>self_</span><span class=special>) {}
</span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>call_method</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;(</span><span class=identifier>self</span><span class=special>, </span><span class=string>&quot;f&quot;</span><span class=special>); }
</span><span class=keyword>int </span><span class=identifier>default_f</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>Base</span><span class=special>::</span><span class=identifier>f</span><span class=special>(); } // &lt;&lt;=== ***</span><span class=identifier>ADDED</span><span class=special>***
</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self</span><span class=special>;
};
</span></pre></code>
<p>
Then, Boost.Python needs to keep track of 1) the dispatch function <tt>f</tt> and
2) the forwarding function to its default implementation <tt>default_f</tt>.
There's a special <tt>def</tt> function for this purpose. Here's how it is
applied to our example above:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>, </span><span class=identifier>BaseWrap</span><span class=special>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>)
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, &amp;</span><span class=identifier>Base</span><span class=special>::</span><span class=identifier>f</span><span class=special>, &amp;</span><span class=identifier>BaseWrap</span><span class=special>::</span><span class=identifier>default_f</span><span class=special>)
</span></pre></code>
<p>
Note that we are allowing <tt>Base</tt> objects to be instantiated this time,
unlike before where we specifically defined the <tt>class_&lt;Base&gt;</tt> with
<tt>no_init</tt>.</p>
<p>
In Python, the results would be as expected:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>base </span><span class=special>= </span><span class=identifier>Base</span><span class=special>()
&gt;&gt;&gt; </span><span class=keyword>class </span><span class=identifier>Derived</span><span class=special>(</span><span class=identifier>Base</span><span class=special>):
... </span><span class=identifier>def </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
... </span><span class=keyword>return </span><span class=number>42
</span><span class=special>...
&gt;&gt;&gt; </span><span class=identifier>derived </span><span class=special>= </span><span class=identifier>Derived</span><span class=special>()
</span></pre></code>
<p>
Calling <tt>base.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>base</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>0
</span></pre></code>
<p>
Calling <tt>derived.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>42
</span></pre></code>
<p>
Calling <tt>call_f</tt>, passing in a <tt>base</tt> object:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>base</span><span class=special>)
</span><span class=number>0
</span></pre></code>
<p>
Calling <tt>call_f</tt>, passing in a <tt>derived</tt> object:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>derived</span><span class=special>)
</span><span class=number>42
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="deriving_a_python_class.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_operators_special_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -60,6 +60,16 @@
<a href="doc/class_virtual_functions.html">Class Virtual Functions</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/deriving_a_python_class.html">Deriving a Python Class</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/virtual_functions_with_default_implementations.html">Virtual Functions with Default Implementations</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/class_operators_special_functions.html">Class Operators/Special Functions</a>
@@ -75,11 +85,21 @@
<a href="doc/call_policies.html">Call Policies</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/overloading.html">Overloading</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/default_arguments.html">Default Arguments</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/auto_overloading.html">Auto-Overloading</a>
</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/object_interface.html">Object Interface</a>
@@ -105,6 +125,16 @@
<a href="doc/enums.html">Enums</a>
</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/embedding.html">Embedding</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/using_the_interpreter.html">Using the interpreter</a>
</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/iterators.html">Iterators</a>
@@ -115,9 +145,29 @@
<a href="doc/exception_translation.html">Exception Translation</a>
</td>
</tr>
<tr>
<td class="toc_cells_L0">
<a href="doc/general_techniques.html">General Techniques</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/creating_packages.html">Creating Packages</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/extending_wrapped_objects_in_python.html">Extending Wrapped Objects in Python</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/reducing_compiling_time.html">Reducing Compiling Time</a>
</td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002 David Abrahams<br>Copyright &copy; 2002 Joel de Guzman<br><br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with

View File

@@ -13,7 +13,7 @@
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">April 2002 Progress Report</h2>
</td>
</tr>
@@ -45,7 +45,7 @@ of work got done...
<h3><a name="arity">Arbitrary Arity Support</a></h3>
I began using the <a
href="../../../preprocessor/doc/index.htm">Boost.Preprocessor</a>
href="../../../preprocessor/doc/index.html">Boost.Preprocessor</a>
metaprogramming library to generate support for functions and member
functions of arbitrary arity, which was, to say the least, quite an
adventure. The feedback cycle resulting from my foray into
@@ -154,7 +154,7 @@ documentation).
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
3 May, 2002
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>

View File

@@ -5,7 +5,7 @@
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
<title>Boost.Python - CallPolicies Concept</title>
</head>
@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">CallPolicies Concept</h2>
</td>
@@ -136,7 +136,8 @@
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
19 May, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -1,7 +1,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
<title>Boost.Python - Dereferenceable Concept</title>
</head>
<body link="#0000ff" vlink="#800080">
@@ -12,7 +12,7 @@
<h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Dereferenceable Concept</h2>
</td>
</tr>
@@ -28,35 +28,40 @@
<h2><a name="introduction"></a>Introduction</h2>
<p>Instances of a dereferenceable type can be used like a pointer to access an lvalue.
<p>Instances of a Dereferenceable type can be used like a pointer to access an lvalue.
<h2><a name="concept-requirements"></a>Concept Requirements</h2>
<h3><a name="Dereferenceable-concept"></a>Dereferenceable Concept</h3>
<p>In the table below, <code><b>x</b></code> denotes an object whose
type is a model of Dereferenceable.
<p>In the table below, <code><b>T</b></code> is a model of
Dereferenceable, and <code><b>x</b></code> denotes an object of
type <code>T</code>. In addition, all pointers are Dereferenceable.
<table summary="Dereferenceable expressions" border="1" cellpadding="5">
<tr>
<td><b>Expression</b></td>
<td><b>Requirements</b></td>
<td><b>Result</b></td>
<td><b>Operational Semantics</b></td>
</tr>
<tr>
<td valign="top"><code>*x</code></td>
<td>An lvalue
<td><code>get_pointer(x)</code></td>
<td>convertible to <code><a href="pointee.html#pointee-spec">pointee</a>&lt;T&gt;::type*</code>
<td><code>&amp;*x</code>, or a null pointer
</tr>
<tr>
</table>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
10 May, 2002
18 December, 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i>
Abrahams</a> 2002-2003. All Rights Reserved.</i>
<p>Permission to copy, use, modify, sell
and distribute this software is granted provided this copyright notice appears

View File

@@ -1,7 +1,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
<title>Boost.Python - Extractor Concept</title>
</head>
<body link="#0000ff" vlink="#800080">
@@ -12,7 +12,7 @@
<h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Extractor Concept</h2>
</td>
</tr>
@@ -79,7 +79,7 @@ are layout-compatible with PyObject.
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
22 May, 2002
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave

View File

@@ -1,7 +1,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
<title>Boost.Python - Holder Concept</title>
</head>
<body link="#0000ff" vlink="#800080">
@@ -12,7 +12,7 @@
<h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">HolderGenerator Concept</h2>
</td>
</tr>
@@ -57,7 +57,7 @@ type.
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
20 May, 2002
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave

View File

@@ -13,7 +13,7 @@
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">June 2002 Progress Report</h2>
</td>
</tr>
@@ -217,7 +217,7 @@ you'll just have to wait till next month (hopefully the beginning).
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
19 July, 2002
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>

View File

@@ -13,7 +13,7 @@
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">March 2002 Progress Report</h2>
</td>
</tr>
@@ -225,7 +225,7 @@ worth doing anything about it.
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
1 April, 2002
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>

View File

@@ -13,7 +13,7 @@
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">May 2002 Progress Report</h2>
</td>
</tr>
@@ -54,7 +54,7 @@ focused on reducing the support burden. In recent weeks, responding to
requests for support, espcially surrounding building the library, had
begun to impede progress on development. There was a major push to
release a stable 1.28.0 of Boost, including documentation of <a
href="../../../../tools/build/index.html">Boost.Build</a> and specific
href="../../../../tools/build/v1/build_system.htm">Boost.Build</a> and specific
<a href="../building.html">instructions</a> for building Boost.Python
v1. The documentation for Boost.Python v2 was also updated as
described <a href="#documentation">here</a>.
@@ -70,7 +70,7 @@ described <a href="#documentation">here</a>.
Martin Casado which uncovered the key mechanism required to allow
shared libraries to use functions from the Python executable. The
current solution used in Boost.Build relies on a <a
href="../../../../tools/build/gen_aix_import_file.py">Python
href="../../../../tools/build/v1/gen_aix_import_file.py">Python
Script</a> as part of the build process. This is not a problem for
Boost.Python, as Python will be available. However, the commands
issued by the script are so simple that a 100%-pure-Boost.Jam
@@ -84,8 +84,7 @@ described <a href="#documentation">here</a>.
Support for exposing C++ operators and functions as the corresponding
Python special methods was added. Thinking that the Boost.Python
<a href="../special.html#numeric">v1 interface</a> was a little too
esoteric (especially the use of
v1 interface was a little too esoteric (especially the use of
<code>left_operand&lt;...&gt;/right_operand&lt;...&gt;</code> for
asymmetric operands), I introduced a simple form of <a
href="http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html">expression
@@ -155,7 +154,7 @@ This forced the exposure of the <a
href="http://www.python.org/2.2/descrintro.html#property"><code>property</code></a>
interface used internally to implement the data member exposure
facility described in <a
href="Mar2002#data_members">March</a>. Properties are an
href="Mar2002.html#data_members">March</a>. Properties are an
incredibly useful idiom, so it's good to be able to provide them
at little new development cost.
@@ -212,7 +211,7 @@ Major updates were made to the following pages:
<blockquote>
<dl>
<dt><a href="call.html">call.html</a><dd> <dt><a href="updated">updated</a><dd>
<dt><a href="call.html">call.html</a><dd> <dt>updated<dd>
<dt><a href="class.html">class.html</a><dd>
<dt><a href="reference.html">reference.html</a><dd>
</dl>
@@ -300,7 +299,7 @@ to these issues will probably have to be formalized before long.
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
11 June, 2002
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">ObjectWrapper and TypeWrapper Concepts</h2>
</td>
@@ -139,7 +139,8 @@ instances of the associated Python type will be considered a match.
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
30 Sept, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -1,7 +1,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../../../boost.css">
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
<title>Boost.Python - ResultConverter Concept</title>
</head>
<body link="#0000ff" vlink="#800080">
@@ -12,7 +12,7 @@
<h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">ResultConverter Concept</h2>
</td>
</tr>

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Acknowledgments</h2>
</td>
@@ -31,19 +31,57 @@
<p><a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a> is
the architect, designer, and implementor of <b>Boost.Python</b>.</p>
<p><a href="mailto:brett.calcott@paradise.net.nz">Brett Calcott</a>
contributed and maintains the Visual Studio project files and
documentation.</p>
<p><a href="mailto:Gottfried.Ganssauge-at-haufe.de">Gottfried
Ganßauge</a> supplied support for opaque pointer conversions,
complete with documentation and a regression test (and I didn't
even have to ask him for those)!
<p>Joel de Guzman implemented the <a href="overloads.html">default
argument support</a> and wrote the excellent tutorial documentation.</p>
argument support</a> and wrote the excellent <a href=
"../tutorial/index.html">tutorial documentation</a>.</p>
<p><a href="../../../../people/ralf_w_grosse_kunstleve.htm">Ralf W.
Grosse-Kunstleve</a> implemented the <a href="pickle.html">pickle
support</a>, and has enthusiastically supported the library since its
birth, contributing to design decisions and providing invaluable
real-world insight into user requirements. Ralf has written some
extensions for converting C++ containers that I hope will be incorporated
into the library soon. He also implemented the cross-module support in
the first version of Boost.Python. More importantly, Ralf makes sure
nobody forgets the near-perfect synergy of C++ and Python for solving the
problems of large-scale software construction.</p>
real-world insight into user requirements. Ralf has written some <a href=
"faq.html#question2">extensions</a> for converting C++ containers that I
hope will be incorporated into the library soon. He also implemented the
cross-module support in the first version of Boost.Python. More
importantly, Ralf makes sure nobody forgets the near-perfect synergy of
C++ and Python for solving the problems of large-scale software
construction.</p>
<p><a href="../../../../people/aleksey_gurtovoy.htm">Aleksey Gurtovoy</a>
wrote an incredible C++ <a href="http://www.mywikinet.com/mpl">Template
Metaprogramming Library</a> which allows Boost.Python to perform much of
its compile-time magic. In addition, Aleksey very generously contributed
his time and deep knowledge of the quirks of various buggy compilers to
help us get around problems at crucial moments.</p>
<p><a href="../../../../people/paul_mensonides.htm">Paul Mensonides</a>,
building on the work <a href="../../../../people/vesa_karvonen.htm">Vesa
Karvonen</a>, wrote a similarly amazing <a href=
"../../../preprocessor/doc/index.html">Preprocessor Metaprogramming
Library</a>, and generously contributed the time and expertise to get it
working in the Boost.Python library, rewriting much of Boost.Python to
use the new preproccessor metaprogramming constructs and helping us to
work around buggy and slow C++ preprocessors.</p>
<p><a href="mailto:nicodemus-at-globalite.com.br">Bruno da Silva de
Oliveira</a> contributed the ingenious <a
href="../../pyste/index.html">Pyste</a> (&quot;Pie-Steh&quot;)
code generator.
<p><a href="mailto:nickm@sitius.com">Nikolay Mladenov</a> contributed
<code>staticmethod</code> support.</p>
<p>Martin Casado solved some sticky problems which allow us to build the
Boost.Python shared library for AIX's crazy dynamic linking model.</p>
<p><a href="mailto:achim@procoders.net">Achim Domma</a> contributed some
of the <a href="reference.html#object_wrappers">Object Wrappers</a> and
@@ -53,9 +91,6 @@
definition syntax. Pearu Pearson wrote some of the test cases that are in
the current test suite.</p>
<p>Martin Casado solved some sticky problems which allow us to build the
Boost.Python shared library for AIX's crazy dynamic linking model.</p>
<p>The development of this version of Boost.Python was funded in part by
the <a href="http://www.llnl.gov/">Lawrence Livermore National
Laboratories</a> and by the <a href="http://cci.lbl.gov/">Computational
@@ -63,8 +98,21 @@
Laboratories.</p>
<p><a href="http://kogs-www.informatik.uni-hamburg.de/~koethe/">Ullrich
Koethe</a> provided the implementation of inheritance and special
method/operator support in the first version of Boost.Python.</p>
Koethe</a> had independently developed a similar system. When he
discovered Boost.Python v1, he generously contributed countless hours of
coding and much insight into improving it. He is responsible for an early
version of the support for function overloading and wrote the support for
reflecting C++ inheritance relationships. He has helped to improve
error-reporting from both Python and C++ (we hope to do as well in v2
again soon), and has designed the original support for exposing numeric
operators, including a way to avoid explicit coercion by means of
overloading.</p>
<p>The members of the boost mailing list and the Python community
supplied invaluable early feedback. In particular, Ron Clarke, Mark
Evans, Anton Gluck, Chuck Ingold, Prabhu Ramachandran, and Barry Scott
took the brave step of trying to use Boost.Python while it was still in
early stages of development.</p>
<p>The first version of Boost.Python would not have been possible without
the support of Dragon Systems, which supported its development and
@@ -73,7 +121,7 @@
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
08 October, 2002
26 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>

View File

@@ -3,7 +3,7 @@
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/args.hpp&gt;</h2>
</td>
@@ -35,7 +35,31 @@
<dt><a href="#keyword-expression"><i>keyword-expressions</i></a></dt>
<dt><a href="#functions">Functions</a></dt>
<dt><a href="#classes">Classes</a></dt>
<dd>
<dl class="page-index">
<dt><a href="#arg-spec">class <code>arg</code></a></dt>
<dd>
<dl class="page-index">
<dt><a href="#arg-synopsis">class <code>arg</code>
synopsis</a></dt>
<dt><a href="#arg-ctor">class <code>arg</code>
constructor</a></dt>
<dt><a href="#arg-operator">class <code>arg</code> template
<code>operator =</code></a></dt>
</dl>
</dd>
</dl>
</dd>
<dt><a href="#keyword-expression-operators"><i>Keyword-expression</i>
operator <code>,</code></a></dt>
<dt><a href="#functions">Functions (deprecated)</a></dt>
<dd>
<dl class="page-index">
@@ -57,27 +81,95 @@
<p>A <b>keyword-expression</b> results in an object which holds a
sequence of <a href="definitions.html#ntbs">ntbs</a>es, and whose type
encodes the number of keywords specified.</p>
encodes the number of keywords specified. The <b>keyword-expression</b>
may contain default values for some or all of the keywords it holds</p>
<h2><a name="functions"></a>Functions</h2>
<h2><a name="classes"></a>Classes</h2>
<h3><a name="args-spec"></a><code>args(</code>...<code>)</code></h3>
<h3><a name="arg-spec"></a><code>class arg;</code></h3>
<p>The objects of class arg are keyword-expressions holding one keyword (
size one )</p>
<h4><a name="arg-synopsis"></a>Class <code>arg</code> synopsis</h4>
<pre>
<i>unspecified1</i> args(char const*);
<i>unspecified2</i> args(char const*, char const*);
.
.
.
<i>unspecifiedN</i> args(char const*, char const*, ... char const*);
namespace boost { namespace python
{
struct arg
{
template &lt;class T&gt;
arg &amp;perator = (T const &amp;value);
explicit arg (char const *name){elements[0].name = name;}
};
}}
</pre>
<h4><a name="arg-ctor"></a>Class <code>arg</code> constructor</h4>
<pre>
arg(char const* name);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> Every argument must be a <a href=
<dt><b>Requires:</b> The argument must be a <a href=
"definitions.html#ntbs">ntbs</a>.</dt>
<dt><b>Returns:</b> an object representing a <a href=
"#keyword-expression"><i>keyword-expression</i></a> encapsulating the
arguments passed.</dt>
<dt><b>Effects:</b> Constructs an <code>arg</code> object holding a
keyword with name <code>name</code>.</dt>
</dl>
<h4><a name="arg-operator"></a>Class <code>arg</code> operator =</h4>
<pre>
template &lt;class T&gt; arg &amp;operator = (T const &amp;value);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> The argument must convertible to python.</dt>
<dt><b>Effects:</b> Assigns default value for the keyword.</dt>
<dt><b>Returns:</b> Reference to <code>this</code>.</dt>
</dl>
<h2><a name="keyword-expression-operators"><i>Keyword-expression</i>
operator <code>,</code></a></h2>
<pre>
<i>keyword-expression</i> operator , (<i>keyword-expression</i>, const arg &amp;kw) const
<i>keyword-expression</i> operator , (<i>keyword-expression</i>, const char *name) const;
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> The argument <code>name</code> must be a <a href=
"definitions.html#ntbs">ntbs</a>.</dt>
<dt><b>Effects:</b> Extends the <i>keyword-expression</i> argument with
one more keyword.</dt>
<dt><b>Returns:</b> The extended <i>keyword-expression</i>.</dt>
</dl>
<h2><font color="#7F7F7F"><a name="functions"></a>Functions
(deprecated)</font></h2>
<h3><a name="args-spec"></a><code><font color=
"#7F7F7F">args</font>(</code>...<code>)</code></h3>
<pre>
<font color="#7F7F7F"> <i>unspecified1</i> args(char const*);
<i>unspecified2</i> args(char const*, char const*);
.
.
.
<i>unspecifiedN</i> args(char const*, char const*, ... char const*);
</font>
</pre>
<dl class="function-semantics">
<dt><font color="#7F7F7F"><b>Requires:</b> Every argument must be a <a
href="definitions.html#ntbs">ntbs</a>.</font></dt>
<dt><font color="#7F7F7F"><b>Returns:</b> an object representing a <a
href="#keyword-expression"><i>keyword-expression</i></a> encapsulating
the arguments passed.</font></dt>
</dl>
<h2><a name="examples"></a>Example</h2>
@@ -85,19 +177,21 @@
#include &lt;boost/python/def.hpp&gt;
using namespace boost::python;
int f(int x, int y, int z);
int f(double x, double y, double z=0.0, double w=1.0);
BOOST_PYTHON_MODULE(xxx)
{
def("f", f, args("x", "y", "z"));
def("f", f
, ( arg("x"), "y", arg("z")=0.0, arg("w")=1.0 )
);
}
</pre>
<p>Revised 05 November, 2001</p>
<p>Revised 01 August, 2003</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002-2003. All
Rights Reserved.</i></p>
</body>
</html>

View File

@@ -13,7 +13,7 @@
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Bibliography</h2>
</td>
</tr>
@@ -23,7 +23,7 @@
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2002
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>

View File

@@ -13,7 +13,7 @@
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;call.hpp&gt;</h2>
</td>
</tr>

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;call_method.hpp&gt;</h2>
</td>
@@ -112,7 +112,7 @@ class Base_callback : public Base
public:
Base_callback(PyObject* self) : m_self(self) {}
char const* class_name() const { return <b>call_method</b>(m_self, "class_name"); }
char const* class_name() const { return <b>call_method</b>&lt;char const*&gt;(m_self, "class_name"); }
char const* Base_name() const { return Base::class_name(); }
private:
PyObject* const m_self;
@@ -147,7 +147,8 @@ BOOST_PYTHON_MODULE(my_module)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
28 Sept, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Calling Python Functions and Methods</h2>
</td>
@@ -240,7 +240,8 @@ void apply(PyObject* callable, X&amp; x)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
17 April, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -3,7 +3,7 @@
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
@@ -21,7 +21,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Headers &lt;boost/python/class.hpp&gt;,
&lt;boost/python/class_fwd.hpp&gt;</h2>
@@ -212,7 +212,7 @@
namespace boost { namespace python
{
template &lt;class T
<font color="#007F00"> , class Bases = bases&lt;&gt;
<font color="#007F00"> , class Bases = bases&lt;&gt;
, class HeldType = T
, class NonCopyable = <i>unspecified</i>
&gt;
@@ -242,6 +242,9 @@ namespace boost { namespace python
template &lt;class Fn, class A1, class A2, class A3&gt;
class_&amp; def(char const* name, Fn fn, A1 const&amp;, A2 const&amp;, A3 const&amp;);
// declaring method as static
class_&amp; staticmethod(char const* name);
// exposing operators
template &lt;<i>unspecified</i>&gt;
class_&amp; def(<a href=
@@ -258,15 +261,27 @@ namespace boost { namespace python
template &lt;class D&gt;
class_&amp; def_readwrite(char const* name, D T::*pm);
// exposing static data members
template &lt;class D&gt;
class_&amp; def_readonly(char const* name, D const&amp; d);
template &lt;class D&gt;
class_&amp; def_readwrite(char const* name, D&amp; d);
// property creation
template &lt;class Get&gt;
void add_property(char const* name, Get const&amp; fget);
template &lt;class Get, class Set&gt;
void add_property(char const* name, Get const&amp; fget, Set const&amp; fset);
template &lt;class Get&gt;
void add_static_property(char const* name, Get const&amp; fget);
template &lt;class Get, class Set&gt;
void add_static_property(char const* name, Get const&amp; fget, Set const&amp; fset);
// pickle support
template &lt;typename PickleSuite&gt;
self&amp; def_pickle(PickleSuite const&amp;);
self&amp; enable_pickling();
};
}}
</pre>
@@ -344,10 +359,11 @@ class_&amp; def(Init init_expr);
generated constructs an object of <code>HeldType</code> according to
the semantics described <a href="#HeldType">above</a>, using a copy of
<code>init_expr</code>'s <a href="CallPolicies.html">call policies</a>.
If the longest <a href="init.html#init-expressions">valid prefix</a> of <code>Init</code> contains <em>N</em>
types and <code>init_expr</code> holds <em>M</em> keywords, an initial
sequence of the keywords are used for all but the first
<em>N</em>&nbsp;-&nbsp;<em>M</em> arguments of each overload.</dt>
If the longest <a href="init.html#init-expressions">valid prefix</a> of
<code>Init</code> contains <em>N</em> types and <code>init_expr</code>
holds <em>M</em> keywords, an initial sequence of the keywords are used
for all but the first <em>N</em>&nbsp;-&nbsp;<em>M</em> arguments of
each overload.</dt>
<dt><b>Returns:</b> <code>*this</code></dt>
@@ -378,20 +394,20 @@ class_&amp; def(char const* name, Fn fn, A1 const&amp; a1, A2 const&amp; a2, A3
<li>
If <code>a1</code> is the result of an <a href=
"overloads.html#overload-dispatch-expression"><em>overload-dispatch-expression</em></a>,
only the second form is allowed and fn must be a pointer
to function or pointer to member function whose <a
href="definitions.html#arity">arity</a> is the same as A1's <a href=
"overloads.html#overload-dispatch-expression"><em>maximum arity</em></a>.
only the second form is allowed and fn must be a pointer to
function or pointer to member function whose <a href=
"definitions.html#arity">arity</a> is the same as A1's <a href=
"overloads.html#overload-dispatch-expression"><em>maximum
arity</em></a>.
<dl>
<dt><b>Effects:</b> For each prefix <em>P</em> of
<code>Fn</code>'s sequence of argument types, beginning
with the one whose length is <code>A1</code>'s <a href=
"overloads.html#overload-dispatch-expression"><em>minimum
arity</em></a>, adds a
<code><em>name</em>(</code>...<code>)</code> method
overload to the extension class. Each overload generated
invokes
<code>Fn</code>'s sequence of argument types, beginning with
the one whose length is <code>A1</code>'s <a href=
"overloads.html#overload-dispatch-expression"><em>minimum
arity</em></a>, adds a
<code><em>name</em>(</code>...<code>)</code> method overload to
the extension class. Each overload generated invokes
<code>a1</code>'s call-expression with <em>P</em>, using a copy
of <code>a1</code>'s <a href="CallPolicies.html">call
policies</a>. If the longest valid prefix of <code>A1</code>
@@ -477,6 +493,37 @@ class_&amp; def(char const* name, Fn fn, A1 const&amp; a1, A2 const&amp; a2, A3
<dt><b>Returns:</b> <code>*this</code></dt>
</dl>
<pre>
class_&amp; staticmethod(char const* name);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is an <a href=
"definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
"http://www.python.org/doc/current/ref/identifiers.html">identifier
naming rules</a>, and corresponds to a method whose overloads have all
been defined.</dt>
<dt><b>Effects:</b> Replaces the existing named attribute <i>x</i> with
the result of invoking <code>staticmethod(</code><i>x</i><code>)</code>
in Python. Specifies that the corresponding method is static and
therefore no object instance will be passed to it. This is equivalent
to the Python statement:</dt>
<dd>
<pre>
setattr(self, name, staticmethod(getattr(self, name)))
</pre>
</dd>
<dt><b>Note:</b> Attempting to invoke <code>def(name,...)</code> after
invoking <code>staticmethod(name)</code> will <a href=
"definitions.html#raise">raise</a> a RuntimeError.</dt>
<dt><b>Returns:</b> <code>*this</code></dt>
</dl>
<br>
<pre>
template &lt;<i>unspecified</i>&gt;
class_&amp; def(<a href=
"operators.html#operator_-spec">detail::operator_</a>&lt;unspecified&gt;);
@@ -529,7 +576,7 @@ void add_property(char const* name, Get const&amp; fget, Set const&amp; fset);
naming rules</a>.</dt>
<dt><b>Effects:</b> Creates a new Python <a href=
"http://www.python.org/current/descrintro.html#property"><code>property</code></a>
"http://www.python.org/2.2.2/descrintro.html#property"><code>property</code></a>
class instance, passing <code><a href=
"object.html#object-spec-ctors">object</a>(fget)</code> (and <code><a
href="object.html#object-spec-ctors">object</a>(fset)</code> in the
@@ -544,8 +591,40 @@ void add_property(char const* name, Get const&amp; fget, Set const&amp; fset);
</dl>
<br>
<pre>
template &lt;class Get&gt;
void add_static_property(char const* name, Get const&amp; fget);
template &lt;class Get, class Set&gt;
void add_static_property(char const* name, Get const&amp; fget, Set const&amp; fset);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is an <a href=
"definitions.html#ntbs">ntbs</a> which conforms to Python's <a href=
"http://www.python.org/doc/current/ref/identifiers.html">identifier
naming rules</a>.</dt>
<dt><b>Effects:</b> Creates a Boost.Python.StaticProperty object,
passing <code><a href=
"object.html#object-spec-ctors">object</a>(fget)</code> (and <code><a
href="object.html#object-spec-ctors">object</a>(fset)</code> in the
second form) to its constructor, then adds that property to the Python
class under construction with the given attribute <code>name</code>.
StaticProperty is a special subclass of Python's <a href=
"http://www.python.org/2.2.2/descrintro.html#property"><code>property</code></a>
class which can be called without an initial <code>self</code>
argument.</dt>
<dt><b>Returns:</b> <code>*this</code></dt>
<dt><b>Rationale:</b> Allows users to easily expose functions that can
be invoked from Python with static attribute access syntax.</dt>
</dl>
<br>
<pre>
template &lt;class D&gt;
class_&amp; def_readonly(char const* name, D T::*pm);
template &lt;class D&gt;
class_&amp; def_readonly(char const* name, D const&amp; d);
</pre>
<dl class="function-semantics">
@@ -561,17 +640,26 @@ class_&amp; def_readonly(char const* name, D T::*pm);
this-&gt;add_property(name, <a href=
"data_members.html#make_getter-spec">make_getter</a>(pm));
</pre>
and
<pre>
this-&gt;add_static_property(name, <a href=
"data_members.html#make_getter-spec">make_getter</a>(pm));
</pre>
respectively.<br>
<br>
</dd>
<dt><b>Returns:</b> <code>*this</code></dt>
<dt><b>Rationale:</b> Allows users to easily expose a class' data
member such that it can be inspected from Python with a natural
syntax.</dt>
member or free variable such that it can be inspected from Python with
a natural syntax.</dt>
</dl>
<pre>
template &lt;class D&gt;
class_&amp; def_readwrite(char const* name, D T::*pm);
template &lt;class D&gt;
class_&amp; def_readwrite(char const* name, D&amp; d);
</pre>
<dl class="function-semantics">
@@ -583,13 +671,21 @@ this-&gt;add_property(name, <a href=
"data_members.html#make_getter-spec">make_getter</a>(pm), <a href=
"data_members.html#make_setter-spec">make_setter</a>(pm));
</pre>
and
<pre>
this-&gt;add_static_property(name, <a href=
"data_members.html#make_getter-spec">make_getter</a>(pm), <a href=
"data_members.html#make_setter-spec">make_setter</a>(pm));
</pre>
respectively.<br>
<br>
</dd>
<dt><b>Returns:</b> <code>*this</code></dt>
<dt><b>Rationale:</b> Allows users to easily expose a class' data
member such that it can be inspected and set from Python with a natural
syntax.</dt>
<dt><b>Rationale:</b> Allows users to easily expose a class' data or
free variable member such that it can be inspected and set from Python
with a natural syntax.</dt>
</dl>
<pre>
template &lt;typename PickleSuite&gt;
@@ -597,27 +693,36 @@ class_&amp; def_pickle(PickleSuite const&amp;);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> PickleSuite must be publically derived from
<a href="pickle.html"
><code>pickle_suite</code></a>.</dt>
<dt><b>Requires:</b> PickleSuite must be publically derived from <a
href="pickle.html"><code>pickle_suite</code></a>.</dt>
<dt><b>Effects:</b> Defines a legal combination of the special
attributes and methods:
<code>__getinitargs__</code>,
<code>__getstate__</code>,
<code>__setstate__</code>,
<code>__getstate_manages_dict__</code>,
<code>__safe_for_unpickling__</code>,
<code>__reduce__</code>
</dt>
attributes and methods: <code>__getinitargs__</code>,
<code>__getstate__</code>, <code>__setstate__</code>,
<code>__getstate_manages_dict__</code>,
<code>__safe_for_unpickling__</code>, <code>__reduce__</code></dt>
<dt><b>Returns:</b> <code>*this</code></dt>
<dt><b>Rationale:</b> Provides an
<a href="pickle.html"
>easy to use high-level interface</a>
for establishing complete pickle support for the wrapped class.
The user is protected by compile-time consistency checks.</dt>
<dt><b>Rationale:</b> Provides an <a href="pickle.html">easy to use
high-level interface</a> for establishing complete pickle support for
the wrapped class. The user is protected by compile-time consistency
checks.</dt>
</dl>
<br>
<pre>
class_&amp; enable_pickling();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> Defines the <code>__reduce__</code> method and
the <code>__safe_for_unpickling__</code> attribute.
<dt><b>Returns:</b> <code>*this</code></dt>
<dt><b>Rationale:</b> Light-weight alternative to
<code>def_pickle()</code>. Enables implementation of
<a href="pickle.html">pickle support</a> from Python.</dt>
</dl>
<br>
@@ -685,7 +790,7 @@ class_&lt;Derived, bases&lt;Base&gt; &gt;("Derived");
</pre>
Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
29 Sept, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
5 August, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href=

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Configuration</h2>
</td>
@@ -47,22 +47,22 @@
<h2><a name="app-defined"></a>Application Defined Macros</h2>
<p>These are the macros that may be defined by an application using
<b>Boost.Python</b>. Note that if you extend a strict interpretation of the C++
standard to cover dynamic libraries, using different values of these
macros when compiling different libraries (including extension modules
and the <b>Boost.Python</b> library itself) is a violation of the <a href=
"definitions.html#ODR">ODR</a>. However, we know of no C++
<b>Boost.Python</b>. Note that if you extend a strict interpretation of
the C++ standard to cover dynamic libraries, using different values of
these macros when compiling different libraries (including extension
modules and the <b>Boost.Python</b> library itself) is a violation of the
<a href="definitions.html#ODR">ODR</a>. However, we know of no C++
implementations on which this particular violation is detectable or
causes any problems.</p>
<table summary="application defined macros" width="100%" cellpadding=
"10">
<tr>
<th align="left"><b>Macro</b></td>
<th align="left"><b>Macro</b></th>
<th><b>Default</b></td>
<th><b>Default</b></th>
<th align="left"><b>Meaning</b></td>
<th align="left"><b>Meaning</b></th>
</tr>
<tr>
@@ -70,15 +70,16 @@
<td valign="top" align="center">15</td>
<td valign="top">The maximum <a href="definitions.html#arity">arity</a> of any
function, member function, or constructor to be wrapped, invocation
of a <b>Boost.Python</b> function wich is specified as taking arguments
<td valign="top">The maximum <a href=
"definitions.html#arity">arity</a> of any function, member function,
or constructor to be wrapped, invocation of a <b>Boost.Python</b>
function wich is specified as taking arguments
<code>x1,&nbsp;x2,</code>...<code>X</code><i>n</i>. This includes, in
particular, callback mechanisms such as <code><a href=
"object.html#object-spec">object</a>::operator()(</code>...<code>)</code>
or <code><a href=
"call_method.html#call_method-spec">call_method</a>&lt;R&gt;(</code>...<code>
)</code>.</td>
"call_method.html#call_method-spec">call_method</a>&lt;R&gt;(</code>...
<code>)</code>.</td>
</tr>
<tr>
@@ -86,28 +87,39 @@
<td valign="top" align="center">10</td>
<td valign="top">The maximum number of template arguments to the <code><a href=
<td valign="top">The maximum number of template arguments to the
<code><a href=
"class.html#bases-spec">bases</a>&lt;</code>...<code>&gt;</code>
class template, which is used to specify the bases of a wrapped C++
class..</td>
</tr>
<tr>
<td valign="top"><code>BOOST_PYTHON_STATIC_MODULE</code></td>
<td valign="top" align="center"><i>not&nbsp;defined</i></td>
<td valign="top">If defined, prevents your module initialization
function from being treated as an exported symbol on platforms which
support that distinction in-code</td>
</tr>
</table>
<h2><a name="lib-defined-impl"></a>Library Defined Implementation
Macros</h2>
<p>These macros are defined by <b>Boost.Python</b> and are
implementation details of interest only to implementors and those porting
to new platforms.</p>
<p>These macros are defined by <b>Boost.Python</b> and are implementation
details of interest only to implementors and those porting to new
platforms.</p>
<table summary="library defined implementation macros" width="100%"
cellpadding="10">
<tr>
<th align="left"><b>Macro</b></td>
<th align="left"><b>Macro</b></th>
<th><b>Default</b></td>
<th><b>Default</b></th>
<th align="left"><b>Meaning</b></td>
<th align="left"><b>Meaning</b></th>
</tr>
<tr>
@@ -115,21 +127,21 @@
<td valign="top" align="center"><i>not&nbsp;defined</i></td>
<td valign="top">If defined, this indicates that the type_info comparison across
shared library boundaries does not work on this platform. In other
words, if shared-lib-1 passes <code>typeid(T)</code> to a function in
shared-lib-2 which compares it to <code>typeid(T)</code>, that
comparison may return <code>false</code>. If this macro is #defined,
Boost.Python uses and compares <code>typeid(T).name()</code> instead
of using and comparing the <code>std::type_info</code> objects
directly.</td>
<td valign="top">If defined, this indicates that the type_info
comparison across shared library boundaries does not work on this
platform. In other words, if shared-lib-1 passes
<code>typeid(T)</code> to a function in shared-lib-2 which compares
it to <code>typeid(T)</code>, that comparison may return
<code>false</code>. If this macro is #defined, Boost.Python uses and
compares <code>typeid(T).name()</code> instead of using and comparing
the <code>std::type_info</code> objects directly.</td>
</tr>
</table>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
04 October, 2002
7 January, 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>

View File

@@ -21,7 +21,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/copy_const_reference.hpp&gt;</h2>
@@ -135,8 +135,8 @@ BOOST_PYTHON_MODULE(my_module)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
29 September, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -21,7 +21,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/copy_non_const_reference.hpp&gt;</h2>
@@ -135,8 +135,8 @@ BOOST_PYTHON_MODULE(my_module)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
29 September, 2001
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -3,7 +3,7 @@
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/data_members.hpp&gt;</h2>
@@ -77,7 +77,48 @@ template &lt;class C, class D, class Policies&gt;
<code>C*</code>, and returns the corresponding member <code>D</code>
member of the <code>C</code> object, converted <code>to_python</code>.
If <code>policies</code> is supplied, it will be applied to the
function as described <a href="CallPolicies.html">here</a>.</dt>
function as described <a href="CallPolicies.html">here</a>. Otherwise,
the library attempts to determine whether <code>D</code> is a
user-defined class type, and if so uses <code><a href=
"return_internal_reference.html#return_internal_reference-spec">return_internal_reference</a>&lt;&gt;</code></dt>
<dt>for <code>Policies</code>. Note that this test may inappropriately
choose <code>return_internal_reference&lt;&gt;</code> in some cases
when <code>D</code> is a smart pointer type. This is a known
defect.</dt>
<dt><b>Returns:</b> An instance of <a href=
"object.html#object-spec">object</a> which holds the new Python
callable object.</dt>
</dl>
<pre>
template &lt;class D&gt;
<a href="object.html#object-spec">object</a> make_getter(D const&amp; d);
template &lt;class D, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_getter(D const&amp; d, Policies const&amp; policies);
template &lt;class D&gt;
<a href="object.html#object-spec">object</a> make_getter(D const* p);
template &lt;class D, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_getter(D const* p, Policies const&amp; policies);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>Policies</code> is a model of <a href=
"CallPolicies.html">CallPolicies</a>.</dt>
<dt><b>Effects:</b> Creates a Python callable object which accepts no
arguments and returns <code>d</code> or <code>*p</code>, converted
<code>to_python</code> on demand. If <code>policies</code> is supplied,
it will be applied to the function as described <a href=
"CallPolicies.html">here</a>. Otherwise, the library attempts to
determine whether <code>D</code> is a user-defined class type, and if
so uses <code><a href=
"reference_existing_object.html#reference_existing_object-spec">reference_existing_object</a></code></dt>
<dt>for <code>Policies</code>.</dt>
<dt><b>Returns:</b> An instance of <a href=
"object.html#object-spec">object</a> which holds the new Python
@@ -108,6 +149,34 @@ template &lt;class C, class D, class Policies&gt;
"object.html#object-spec">object</a> which holds the new Python
callable object.</dt>
</dl>
<pre>
template &lt;class D&gt;
<a href="object.html#object-spec">object</a> make_setter(D&amp; d);
template &lt;class D, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_setter(D&amp; d, Policies const&amp; policies);
template &lt;class D&gt;
<a href="object.html#object-spec">object</a> make_setter(D* p);
template &lt;class D, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_setter(D* p, Policies const&amp; policies);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>Policies</code> is a model of <a href=
"CallPolicies.html">CallPolicies</a>.</dt>
<dt><b>Effects:</b> Creates a Python callable object which accepts one
argument, which is converted from Python to <code>D const&amp;</code>
and written into <code>d</code> or <code>*p</code>, respectively. If
<code>policies</code> is supplied, it will be applied to the function
as described <a href="CallPolicies.html">here</a>.</dt>
<dt><b>Returns:</b> An instance of <a href=
"object.html#object-spec">object</a> which holds the new Python
callable object.</dt>
</dl>
<h2><a name="examples"></a>Example</h2>
@@ -147,8 +216,7 @@ BOOST_PYTHON_MODULE_INIT(data_members_example)
<p>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
29 September 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
5 August, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -3,7 +3,7 @@
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/def.hpp&gt;</h2>
</td>
@@ -75,6 +75,12 @@ void def(char const* name, Fn fn, A1 const&amp;, A2 const&amp;, A3 const&amp;);
<dd>
<ul>
<li>If <code>Fn</code> is [derived from] <code><a href=
"object.html#object-spec">object</a></code>, it will be added to
the current scope as a single overload. To be useful,
<code>fn</code> should be <a href=
"http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-6">callable</a>.</li>
<li>
If <code>a1</code> is the result of an <a href=
"overloads.html#overload-dispatch-expression"><em>overload-dispatch-expression</em></a>,
@@ -104,67 +110,52 @@ void def(char const* name, Fn fn, A1 const&amp;, A2 const&amp;, A3 const&amp;);
</dl>
</li>
<li>
Otherwise, a single function overload built around fn (which must
not be null) is added to the <a href="scope.html">current
scope</a>:
<ul>
<li>If fn is a function or member function pointer,
<code>a1</code>-<code>a3</code> (if supplied) may be selected
in any order from the table below.</li>
<li>Otherwise, <code>Fn</code> must be [derived from] <code><a
href="object.html#object-spec">object</a></code>, and
<code>a1-a2</code> (if supplied) may be selcted in any order
from the first two rows of the table below. To be useful,
<code>fn</code> should be <a href=
"http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-6">
callable</a>.</li>
</ul>
<table border="1" summary="def() optional arguments">
<tr>
<th>Memnonic Name</th>
<th>Requirements/Type properties</th>
<th>Effects</th>
</tr>
<tr>
<td>docstring</td>
<td>Any <a href="definitions.html#ntbs">ntbs</a>.</td>
<td>Value will be bound to the <code>__doc__</code> attribute
of the resulting method overload.</td>
</tr>
<tr>
<td>policies</td>
<td>A model of <a href=
"CallPolicies.html">CallPolicies</a></td>
<td>A copy will be used as the call policies of the resulting
method overload.</td>
</tr>
<tr>
<td>keywords</td>
<td>The result of a <a href=
"args.html#keyword-expression"><em>keyword-expression</em></a>
specifying no more arguments than the <a href=
"definitions.html#arity">arity</a> of <code>fn</code>.</td>
<td>A copy will be used as the call policies of the resulting
method overload.</td>
</tr>
</table>
</li>
<li>Otherwise, fn must be a non-null function or member function
pointer, and a single function overload built around fn is added to
the <a href="scope.html">current scope</a>. If any of
<code>a1</code>-<code>a3</code> are supplied, they may be selected
in any order from the table below.</li>
</ul>
<table border="1" summary="def() optional arguments">
<tr>
<th>Memnonic Name</th>
<th>Requirements/Type properties</th>
<th>Effects</th>
</tr>
<tr>
<td>docstring</td>
<td>Any <a href="definitions.html#ntbs">ntbs</a>.</td>
<td>Value will be bound to the <code>__doc__</code> attribute of
the resulting method overload.</td>
</tr>
<tr>
<td>policies</td>
<td>A model of <a href="CallPolicies.html">CallPolicies</a></td>
<td>A copy will be used as the call policies of the resulting
method overload.</td>
</tr>
<tr>
<td>keywords</td>
<td>The result of a <a href=
"args.html#keyword-expression"><em>keyword-expression</em></a>
specifying no more arguments than the <a href=
"definitions.html#arity">arity</a> of <code>fn</code>.</td>
<td>A copy will be used as the call policies of the resulting
method overload.</td>
</tr>
</table>
</dd>
</dl>
@@ -174,6 +165,8 @@ void def(char const* name, Fn fn, A1 const&amp;, A2 const&amp;, A3 const&amp;);
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/args.hpp&gt;
using namespace boost::python;
char const* foo(int x, int y) { return "foo"; }
BOOST_PYTHON_MODULE(def_test)
@@ -184,7 +177,7 @@ BOOST_PYTHON_MODULE(def_test)
<p>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
03 October, 2002
7 March, 2003
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>

135
doc/v2/def_visitor.html Normal file
View File

@@ -0,0 +1,135 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta name="generator" content="Microsoft FrontPage 5.0">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/def_visitor.hpp&gt;</title>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 align="center"><a href="../index.html"><font size="7">Boost.Python</font></a></h1>
<h2 align="center">Header &lt;boost/python/def_visitor.hpp&gt;</h2>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a>
<dt><a href="#classes">Classes</a>
<dd>
<dl class="page-index">
<dt><a href="#def_visitor-spec">Class <code>def_visitor</code></a>
<dd> <a href="#def_visitor-synopsis">Class <code>def_visitor</code>
synopsis</a></dd>
<dd> <a href="#def_visitor-requirements">Class <code>def_visitor</code>
requirements</a></dd>
</dl>
<dt><a href="#examples">Example</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/def_visitor.hpp&gt;</code> provides a generic visitation
interface through which the <a href="class.html">class_</a> <b>def</b> member
functionality can be extended non-intrusively to avoid cluttering the <a href="class.html">class_</a>
interface. It declares the <code>def_visitor&lt;T&gt; </code>class template,
which is parameterized on the derived type <tt>DerivedVisitor</tt>, which provides
the actual <b>def</b> functionality through its <b>visit</b> member functions.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="def_visitor-spec"></a>Class template <code>def_visitor&lt;DerivedVisitor&gt;</code></h3>
<p>The class def_visitor is a base class paramaterized by its derived class. The
def_visitor class is a protocol class. Its derived class, DerivedVisitor, is
expected to have a member function visit. The def_visitor class is never instantiated
directly. Instead, an instance of its subclass, DerivedVisitor,&nbsp; is passed
on as an argument to the <a href="class.html">class_</a> def member function.
<h4>
<a name="def_visitor-synopsis" id="def_visitor-synopsis"></a>Class <code>def_visitor </code>synopsis</h4>
<pre>namespace boost { namespace python {
template &lt;class DerivedVisitor&gt;
class def_visitor {};
}</pre>
<h3><a name="def_visitor-requirements"></a><code>def_visitor </code>requirements</h3>
<p>The <span class="pre">client supplied class </span><span class="pre"></span><tt class="literal"><span class="pre">DerivedVisitor</span></tt>
template parameter is expected to:
<ul>
<li>be privately derived from def_visitor</li>
<li>grant friend access to class def_visitor_access</li>
<li>define either or both visit member functions listed in the table below:</li>
</ul>
<table border class="table">
<tr>
<td width="181" nowrap><b>Expression</b></td>
<td width="85"><b>Return Type</b></td>
<td width="330"><b>Requirements</b></td>
<td width="259"><b>Effects</b></td>
</tr>
<tr>
<td nowrap>visitor.visit(cls)</td>
<td>void</td>
<td>cls is an instance of a <a href="class.html">class_</a>&nbsp; being wrapped
to Python. visitor is a def_visitor derived class.</td>
<td>A call to cls.def(visitor) forwards to this member function.</td>
</tr>
<tr>
<td nowrap>visitor.visit(cls, name, options)</td>
<td>void</td>
<td>cls is a class_ instance, name is a C string. visitor is a def_visitor
derived class. options is a context specific optional argument.</td>
<td>A call to cls.def(name, visitor) or cls.def(name, visitor, options) forwards
to this member function. </td>
</tr>
</table>
<h2><a name="examples"></a>Example</h2>
<pre>class X {/*...*/};<br>
class my_def_visitor : boost::python::def_visitor&lt;my_def_visitor&gt;
{
friend class def_visitor_access;
template &lt;class classT&gt;
void visit(classT&amp; c) const
{
c
.def(&quot;foo&quot;, &amp;my_def_visitor::foo)
.def(&quot;bar&quot;, &amp;my_def_visitor::bar)
;
}
static void foo(X&amp; self);
static void bar(X&amp; self);
};
BOOST_PYTHON_MODULE(my_ext)
{
class_&lt;X&gt;(&quot;X&quot;)
.def(my_def_visitor())
;
}
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->27 August, 2003<!--webbot bot="Timestamp" endspan i-checksum="34484" -->
</p>
<p><i>&copy; Copyright Joel de Guzman 2003. All Rights Reserved.</i>

View File

@@ -14,7 +14,7 @@
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/default_call_policies.hpp&gt;</h2>
@@ -161,8 +161,8 @@ struct return_value_policy : Base
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2001
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Definitions</h2>
</td>
@@ -88,8 +88,8 @@
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
03 October, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/dict.hpp&gt;</h2>
</td>

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/enum.hpp&gt;</h2>
</td>
@@ -87,7 +87,8 @@ namespace boost { namespace python
class enum_ : public <a href="object.html#object-spec">object</a>
{
enum_(char const* name);
inline enum_&lt;T&gt;&amp; value(char const* name, T);
enum_&lt;T&gt;&amp; value(char const* name, T);
enum_&lt;T&gt;&amp; export_values();
};
}}
</pre>
@@ -133,6 +134,21 @@ inline enum_&lt;T&gt;&amp; value(char const* name, T x);
</dl>
<pre>
inline enum_&lt;T&gt;&amp; export_values();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> sets attributes in the current <a
href="scope.html#scope-spec"><code>scope</code></a> with the
same names and values as all enumeration values exposed so far
by calling <code>value()</code></dt>.
<dt><b>Returns:</b> <code>*this</code></dt>
</dl>
<h2><a name="examples"></a>Example(s)</h2>
<p>C++ module definition
@@ -152,6 +168,7 @@ BOOST_PYTHON_MODULE(enums)
enum_&lt;color&gt;(&quot;color&quot;)
.value(&quot;red&quot;, red)
.value(&quot;green&quot;, green)
.export_values()
.value(&quot;blue&quot;, blue)
;
@@ -162,12 +179,23 @@ BOOST_PYTHON_MODULE(enums)
<pre>
&gt;&gt;&gt; from enums import *
&gt;&gt;&gt; identity(red)
enums.color.red
&gt;&gt;&gt; identity(color.red)
enums.color.red
&gt;&gt;&gt; identity(green)
enums.color.green
&gt;&gt;&gt; identity(color.green)
enums.color.green
&gt;&gt;&gt; identity(blue)
Traceback (most recent call last):
File &quot;&lt;stdin&gt;&quot;, line 1, in ?
NameError: name blue' is not defined
&gt;&gt;&gt; identity(color.blue)
enums.color.blue
@@ -192,7 +220,8 @@ TypeError: bad argument type for built-in operation
Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
03 October, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 December, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href=

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/errors.hpp&gt;</h2>
</td>
@@ -275,8 +275,8 @@ same_name2(PyObject* args, PyObject* keywords)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
29 September, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -21,7 +21,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/exception_translator.hpp&gt;</h2>

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/extract.hpp&gt;</h2>
</td>
@@ -216,11 +216,11 @@ BOOST_PYTHON_MODULE(extract_ext)
object x_obj = x_class(3);
// Get a reference to the C++ object out of the Python object
X const&amp; x = extract&lt;X&amp;&gt;(x_obj);
X&amp; x = extract&lt;X&amp;&gt;(x_obj);
assert(x.value() == 3);
}
</pre>
<p>Revised 30 September, 2002</p>
<p>Revised 15 November, 2002</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights

View File

@@ -3,8 +3,8 @@
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
"HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - FAQ</title>
@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Frequently Asked Questions (FAQs)</h2>
</td>
@@ -29,14 +29,141 @@
<hr>
<dl class="page-index">
<dt><a href="#question1">Is return_internal reference
<dt><a href="#funcptr">How can I wrap a function which takes a
function pointer as an argument?</a><dd>
<dt><a href="#dangling">I'm getting the "attempt to return dangling
reference" error. What am I doing wrong?</a></dt>
<dt><a href="#question1">Is return_internal_reference
efficient?</a></dt>
<dt><a href="#question2">How can I wrap containers which take C++
<dt><a href="#question2">How can I wrap functions which take C++
containers as arguments?</a></dt>
</dl>
<h2><a name="question1"></a>Is return_internal reference efficient?</h2>
<dt><a href="#c1204">fatal error C1204:Compiler limit:internal
structure overflow</a></dt>
<dt><a href="#debugging">How do I debug my Python extensions?</a></dt>
<dt><a href="#imul">Why doesn't my <code>*=</code> operator
work?</a></dt>
<dt><a href="#macosx">Does Boost.Python work with Mac OS X?</a></dt>
<dt><a href="#xref">How can I find the existing PyObject that holds a
C++ object?</a></dt>
<dt><a href="#ownership">How can I wrap a function which needs to take
ownership of a raw pointer?</a></dt>
<dt><a href="#slow_compilation">Compilation takes too much time and eats too much memory!
What can I do to make it faster?</a></dt>
<dt><a href="#packages">How do I create sub-packages using Boost.Python?</a></dt>
<dt><a href="#msvcthrowbug"
>error C2064: term does not evaluate to a function taking 2 arguments</a>
</dt>
<dt><a href="#voidptr">How do I handle <tt>void *</tt> conversion?</a></dt>
<dt><a href="#custom_string"
>How can I automatically convert my custom string type to
and from a Python string?</a></dt>
<dt><a href="#topythonconversionfailed">Why is my automatic to-python conversion not being
found?</a></dt>
<dt><a href="#threadsupport">Is Boost.Python thread-aware/compatible with multiple interpreters?</a></dt>
</dl>
<hr>
<h2><a name="funcptr">How can I wrap a function which takes a
function pointer as an argument?</a></h2>
If what you're trying to do is something like this:
<pre>
typedef boost::function&lt;void (string s) &gt; funcptr;
void foo(funcptr fp)
{
fp(&quot;hello,world!&quot;);
}
BOOST_PYTHON_MODULE(test)
{
def(&quot;foo&quot;,foo) ;
}
</pre>
And then:
<pre>
&gt;&gt;&gt; def hello(s):
... print s
...
&gt;&gt;&gt; foo(hello)
hello, world!
</pre>
The short answer is: &quot;you can't&quot;. This is not a
Boost.Python limitation so much as a limitation of C++. The
problem is that a Python function is actually data, and the only
way of associating data with a C++ function pointer is to store it
in a static variable of the function. The problem with that is
that you can only associate one piece of data with every C++
function, and we have no way of compiling a new C++ function
on-the-fly for every Python function you decide to pass
to <code>foo</code>. In other words, this could work if the C++
function is always going to invoke the <em>same</em> Python
function, but you probably don't want that.
<p>If you have the luxury of changing the C++ code you're
wrapping, pass it an <code>object</code> instead and call that;
the overloaded function call operator will invoke the Python
function you pass it behind the <code>object</code>.
<p>For more perspective on the issue, see <a
href="http://aspn.activestate.com/ASPN/Mail/Message/1554837">this
posting</a>.
<hr>
<h2><a name="dangling">I'm getting the "attempt to return dangling
reference" error. What am I doing wrong?</a></h2>
That exception is protecting you from causing a nasty crash. It usually
happens in response to some code like this:
<pre>
period const&amp; get_floating_frequency() const
{
return boost::python::call_method&lt;period const&amp;&gt;(
m_self,"get_floating_frequency");
}
</pre>
And you get:
<pre>
ReferenceError: Attempt to return dangling reference to object of type:
class period
</pre>
<p>In this case, the Python method invoked by <code>call_method</code>
constructs a new Python object. You're trying to return a reference to a
C++ object (an instance of <code>class period</code>) contained within
and owned by that Python object. Because the called method handed back a
brand new object, the only reference to it is held for the duration of
<code>get_floating_frequency()</code> above. When the function returns,
the Python object will be destroyed, destroying the instance of
<code>class period</code>, and leaving the returned reference dangling.
That's already undefined behavior, and if you try to do anything with
that reference you're likely to cause a crash. Boost.Python detects this
situation at runtime and helpfully throws an exception instead of letting
you do that.<br>
&nbsp;</p>
<hr>
<h2><a name="question1"></a>Is return_internal_reference efficient?</h2>
<blockquote>
<b>Q:</b> <i>I have an object composed of 12 doubles. A const&amp; to
@@ -46,7 +173,7 @@
I have the choice of using copy_const_reference or
return_internal_reference. Are there considerations that would lead me
to prefer one over the other, such as size of generated code or memory
overhead?</i>
overhead?</i>
<p><b>A:</b> copy_const_reference will make an instance with storage
for one of your objects, size = base_size + 12 * sizeof(double).
@@ -59,6 +186,7 @@
memory use and less fragmentation, also probably fewer total
cycles.</p>
</blockquote>
<hr>
<h2><a name="question2"></a>How can I wrap functions which take C++
containers as arguments?</h2>
@@ -67,7 +195,7 @@
<ol>
<li>
Using the regular <code>class_&lt;&gt;</code> wrapper:
Using the regular <code>class_&lt;&gt;</code> wrapper:
<pre>
class_&lt;std::vector&lt;double&gt; &gt;("std_vector_double")
.def(...)
@@ -76,13 +204,13 @@ class_&lt;std::vector&lt;double&gt; &gt;("std_vector_double")
</pre>
This can be moved to a template so that several types (double, int,
long, etc.) can be wrapped with the same code. This technique is used
in the file
in the file
<blockquote>
scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h
</blockquote>
in the "scitbx" package. The file could easily be modified for
wrapping std::vector&lt;&gt; instantiations.
wrapping std::vector&lt;&gt; instantiations.
<p>This type of C++/Python binding is most suitable for containers
that may contain a large number of elements (&gt;10000).</p>
@@ -90,19 +218,19 @@ class_&lt;std::vector&lt;double&gt; &gt;("std_vector_double")
<li>
Using custom rvalue converters. Boost.Python "rvalue converters"
match function signatures such as:
match function signatures such as:
<pre>
void foo(std::vector&lt;double&gt; const&amp; array); // pass by const-reference
void foo(std::vector&lt;double&gt; array); // pass by value
</pre>
Some custom rvalue converters are implemented in the file
Some custom rvalue converters are implemented in the file
<blockquote>
scitbx/include/scitbx/boost_python/container_conversions.h
</blockquote>
This code can be used to convert from C++ container types such as
std::vector&lt;&gt; or std::list&lt;&gt; to Python tuples and vice
versa. A few simple examples can be found in the file
versa. A few simple examples can be found in the file
<blockquote>
scitbx/array_family/boost_python/regression_test_module.cpp
@@ -117,7 +245,7 @@ void foo(std::vector&lt;double&gt; array); // pass by value
rvalue converters that convert to a "math_array" type instead of tuples.
This is currently not implemented but is possible within the framework of
Boost.Python V2 as it will be released in the next couple of weeks. [ed.:
this was posted on 2002/03/10]
this was posted on 2002/03/10]
<p>It would also be useful to also have "custom lvalue converters" such
as std::vector&lt;&gt; &lt;-&gt; Python list. These converters would
@@ -132,7 +260,7 @@ void foo(std::vector&lt;double&gt;&amp; array)
}
}
</pre>
Python:
Python:
<pre>
&gt;&gt;&gt; l = [1, 2, 3]
&gt;&gt;&gt; foo(l)
@@ -140,7 +268,7 @@ void foo(std::vector&lt;double&gt;&amp; array)
[2, 4, 6]
</pre>
Custom lvalue converters require changes to the Boost.Python core library
and are currently not available.
and are currently not available.
<p>P.S.:</p>
@@ -152,15 +280,605 @@ cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx
</pre>
<hr>
<p>Revised
<h2><a name="c1204"></a>fatal error C1204:Compiler limit:internal
structure overflow</h2>
<blockquote>
<b>Q:</b> <i>I get this error message when compiling a large source
file. What can I do?</i>
<p><b>A:</b> You have two choices:</p>
<ol>
<li>Upgrade your compiler (preferred)</li>
<li>
Break your source file up into multiple translation units.
<p><code><b>my_module.cpp</b></code>:</p>
<pre>
...
void more_of_my_module();
BOOST_PYTHON_MODULE(my_module)
{
def("foo", foo);
def("bar", bar);
...
more_of_my_module();
}
</pre>
<code><b>more_of_my_module.cpp</b></code>:
<pre>
void more_of_my_module()
{
def("baz", baz);
...
}
</pre>
If you find that a <code><a href=
"class.html#class_-spec">class_</a>&lt;...&gt;</code> declaration
can't fit in a single source file without triggering the error, you
can always pass a reference to the <code>class_</code> object to a
function in another source file, and call some of its member
functions (e.g. <code>.def(...)</code>) in the auxilliary source
file:
<p><code><b>more_of_my_class.cpp</b></code>:</p>
<pre>
void more_of_my_class(class&lt;my_class&gt;&amp; x)
{
x
.def("baz", baz)
.add_property("xx", &amp;my_class::get_xx, &amp;my_class::set_xx)
;
...
}
</pre>
</li>
</ol>
</blockquote>
<hr>
<h2><a name="debugging"></a>How do I debug my Python extensions?</h2>
<p>Greg Burley gives the following answer for Unix GCC users:</p>
<blockquote>
Once you have created a boost python extension for your c++ library or
class, you may need to debug the code. Afterall this is one of the
reasons for wrapping the library in python. An expected side-effect or
benefit of using BPL is that debugging should be isolated to the c++
library that is under test, given that python code is minimal and
boost::python either works or it doesn't. (ie. While errors can occur
when the wrapping method is invalid, most errors are caught by the
compiler ;-).
<p>The basic steps required to initiate a gdb session to debug a c++
library via python are shown here. Note, however that you should start
the gdb session in the directory that contains your BPL my_ext.so
module.</p>
<pre>
(gdb) target exec python
(gdb) run
&gt;&gt;&gt; from my_ext import *
&gt;&gt;&gt; [C-c]
(gdb) break MyClass::MyBuggyFunction
(gdb) cont
&gt;&gt;&gt; pyobj = MyClass()
&gt;&gt;&gt; pyobj.MyBuggyFunction()
Breakpoint 1, MyClass::MyBuggyFunction ...
Current language: auto; currently c++
(gdb) do debugging stuff
</pre>
</blockquote>
<p>Greg's approach works even better using Emacs' "<code>gdb</code>"
command, since it will show you each line of source as you step through
it.</p>
<p>On <b>Windows</b>, my favorite debugging solution is the debugger that
comes with Microsoft Visual C++ 7. This debugger seems to work with code
generated by all versions of Microsoft and Metrowerks toolsets; it's rock
solid and "just works" without requiring any special tricks from the
user.</p>
<p>Raoul Gough has provided the following for gdb on Windows:</p>
<blockquote>
<p>gdb support for Windows DLLs has improved lately, so it is
now possible to debug Python extensions using a few
tricks. Firstly, you will need an up-to-date gdb with support
for minimal symbol extraction from a DLL. Any gdb from version 6
onwards, or Cygwin gdb-20030214-1 and onwards should do. A
suitable release will have a section in the gdb.info file under
Configuration &ndash; Native &ndash; Cygwin Native &ndash;
Non-debug DLL symbols. Refer to that info section for more
details of the procedures outlined here.</p>
<p>Secondly, it seems necessary to set a breakpoint in the
Python interpreter, rather than using ^C to break execution. A
good place to set this breakpoint is PyOS_Readline, which will
stop execution immediately before reading each interactive
Python command. You have to let Python start once under the
debugger, so that it loads its own DLL, before you can set the
breakpoint:</p>
<p>
<pre>
$ gdb python
GNU gdb 2003-09-02-cvs (cygwin-special)
[...]
(gdb) run
Starting program: /cygdrive/c/Python22/python.exe
Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; ^Z
Program exited normally.
(gdb) break *&amp;PyOS_Readline
Breakpoint 1 at 0x1e04eff0
(gdb) run
Starting program: /cygdrive/c/Python22/python.exe
Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
Breakpoint 1, 0x1e04eff0 in python22!PyOS_Readline ()
from /cygdrive/c/WINNT/system32/python22.dll
(gdb) cont
Continuing.
&gt;&gt;&gt; from my_ext import *
Breakpoint 1, 0x1e04eff0 in python22!PyOS_Readline ()
from /cygdrive/c/WINNT/system32/python22.dll
(gdb) # my_ext now loaded (with any debugging symbols it contains)
</pre>
</blockquote>
<h3>Debugging extensions through Boost.Build</h3>
If you are launching your extension module tests with <a href=
"../../../../tools/build/v1/build_system.htm">Boost.Build</a> using the
<code>boost-python-runtest</code> rule, you can ask it to launch your
debugger for you by adding "--debugger=<i>debugger</i>" to your bjam
command-line:
<pre>
bjam -sTOOLS=vc7.1 "--debugger=devenv /debugexe" test
bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
</pre>
It can also be extremely useful to add the <code>-d+2</code> option when
you run your test, because Boost.Build will then show you the exact
commands it uses to invoke it. This will invariably involve setting up
PYTHONPATH and other important environment variables such as
LD_LIBRARY_PATH which may be needed by your debugger in order to get
things to work right.
<hr>
<h2><a name="imul"></a>Why doesn't my <code>*=</code> operator work?</h2>
<blockquote>
<b>Q:</b> <i>I have exported my class to python, with many overloaded
operators. it works fine for me except the</i> <code>*=</code>
<i>operator. It always tells me "can't multiply sequence with non int
type". If I use</i> <code>p1.__imul__(p2)</code> <i>instead of</i>
<code>p1 *= p2</code><i>, it successfully executes my code. What's
wrong with me?</i>
<p><b>A:</b> There's nothing wrong with you. This is a bug in Python
2.2. You can see the same effect in Pure Python (you can learn a lot
about what's happening in Boost.Python by playing with new-style
classes in Pure Python).</p>
<pre>
&gt;&gt;&gt; class X(object):
... def __imul__(self, x):
... print 'imul'
...
&gt;&gt;&gt; x = X()
&gt;&gt;&gt; x *= 1
</pre>
To cure this problem, all you need to do is upgrade your Python to
version 2.2.1 or later.
</blockquote>
<hr>
<h2><a name="macosx"></a>Does Boost.Python work with Mac OS X?</h2>
It is known to work under 10.2.8 and 10.3 using
Apple's gcc 3.3 compiler:
<pre>gcc (GCC) 3.3 20030304 (Apple Computer, Inc. build 1493)</pre>
Under 10.2.8 get the August 2003 gcc update (free at
<a href="http://connect.apple.com/">http://connect.apple.com/</a>).
Under 10.3 get the Xcode Tools v1.0 (also free).
<p>
Python 2.3 is required. The Python that ships with 10.3 is
fine. Under 10.2.8 use these commands to install Python
as a framework:
<pre>./configure --enable-framework
make
make frameworkinstall</pre>
The last command requires root privileges because the target
directory is
<tt>/Library/Frameworks/Python.framework/Versions/2.3</tt>.
However, the installation does not interfere with the Python
version that ships with 10.2.8.
<p>
It is also crucial to increase the <tt>stacksize</tt> before
starting compilations, e.g.:
<pre>limit stacksize 8192k</pre>
If the <tt>stacksize</tt> is too small the build might crash with
internal compiler errors.
<p>
Sometimes Apple's compiler exhibits a bug by printing an error
like the following while compiling a
<tt>boost::python::class_&lt;your_type&gt;</tt>
template instantiation:
<pre>.../inheritance.hpp:44: error: cannot
dynamic_cast `p' (of type `struct cctbx::boost_python::&lt;unnamed&gt;::add_pair*
') to type `void*' (source type is not polymorphic)</pre>
We do not know a general workaround, but if the definition of
<tt>your_type</tt> can be modified the following was found
to work in all cases encountered so far:<pre>struct your_type
{
// before defining any member data
#if defined(__MACH__) &amp;&amp; defined(__APPLE_CC__) &amp;&amp; __APPLE_CC__ == 1493
bool dummy_;
#endif
// now your member data, e.g.
double x;
int j;
// etc.
};</pre>
<hr>
<h2><a name="xref">How can I find the existing PyObject that holds a C++
object?</a></h2>
<blockquote>
"I am wrapping a function that always returns a pointer to an
already-held C++ object."
</blockquote>
One way to do that is to hijack the mechanisms used for wrapping a class
with virtual functions. If you make a wrapper class with an initial
PyObject* constructor argument and store that PyObject* as "self", you
can get back to it by casting down to that wrapper type in a thin wrapper
function. For example:
<pre>
class X { X(int); virtual ~X(); ... };
X* f(); // known to return Xs that are managed by Python objects
// wrapping code
struct X_wrap : X
{
X_wrap(PyObject* self, int v) : self(self), X(v) {}
PyObject* self;
};
handle&lt;&gt; f_wrap()
{
X_wrap* xw = dynamic_cast&lt;X_wrap*&gt;(f());
assert(xw != 0);
return handle&lt;&gt;(borrowed(xw-&gt;self));
}
...
def("f", f_wrap());
class_&lt;X,X_wrap&gt;("X", init&lt;int&gt;())
...
;
</pre>
Of course, if X has no virtual functions you'll have to use
<code>static_cast</code> instead of <code>dynamic_cast</code> with no
runtime check that it's valid. This approach also only works if the
<code>X</code> object was constructed from Python, because
<code>X</code>s constructed from C++ are of course never
<code>X_wrap</code> objects.
<p>Another approach to this requires you to change your C++ code a bit;
if that's an option for you it might be a better way to go. work we've
been meaning to get to anyway. When a <code>shared_ptr&lt;X&gt;</code> is
converted from Python, the shared_ptr actually manages a reference to the
containing Python object. When a shared_ptr&lt;X&gt; is converted back to
Python, the library checks to see if it's one of those "Python object
managers" and if so just returns the original Python object. So you could
just write <code>object(p)</code> to get the Python object back. To
exploit this you'd have to be able to change the C++ code you're wrapping
so that it deals with shared_ptr instead of raw pointers.</p>
<p>There are other approaches too. The functions that receive the Python
object that you eventually want to return could be wrapped with a thin
wrapper that records the correspondence between the object address and
its containing Python object, and you could have your f_wrap function
look in that mapping to get the Python object out.</p>
<hr>
<h2><a name="ownership">How can I wrap a function which needs to take
ownership of a raw pointer?</a></h2>
<blockquote>
<i>Part of an API that I'm wrapping goes something like this:</i>
<pre>
struct A {}; struct B { void add( A* ); }
where B::add() takes ownership of the pointer passed to it.
</pre>
<p><i>However:</i></p>
<pre>
a = mod.A()
b = mod.B()
b.add( a )
del a
del b
# python interpreter crashes
# later due to memory corruption.
</pre>
<p><i>Even binding the lifetime of a</i> to b via
with_custodian_and_ward doesn't prevent the python object a from
ultimately trying to delete the object it's pointing to. Is there a way
to accomplish a 'transfer-of-ownership' of a wrapped C++ object?</p>
<p><i>--Bruce Lowery</i></p>
</blockquote>
Yes: Make sure the C++ object is held by auto_ptr:
<pre>
class_&lt;A, std::auto_ptr&lt;A&gt; &gt;("A")
...
;
</pre>
Then make a thin wrapper function which takes an auto_ptr parameter:
<pre>
void b_insert(B&amp; b, std::auto_ptr&lt;A&gt; a)
{
b.insert(a.get());
a.release();
}
</pre>
Wrap that as B.add. Note that pointers returned via <code><a href=
"manage_new_object.html#manage_new_object-spec">manage_new_object</a></code>
will also be held by <code>auto_ptr</code>, so this transfer-of-ownership
will also work correctly.
<hr>
<h2><a name="slow_compilation">Compilation takes too much time and eats too
much memory! What can I do to make it faster?</a></h2>
<p>
Please refer to the <a href="../tutorial/doc/reducing_compiling_time.html"
>Reducing Compiling Time</a> section in the tutorial.
</p>
<hr>
<h2><a name="packages">How do I create sub-packages using Boost.Python?</a></h2>
<p>
Please refer to the <a href="../tutorial/doc/creating_packages.html"
>Creating Packages</a> section in the tutorial.
</p>
<hr>
<h2><a name="msvcthrowbug"></a>error C2064: term does
not evaluate to a function taking 2 arguments</h2>
<font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
If you see Microsoft Visual C++ 7.1 (MS Visual Studio .NET 2003) issue
an error message like the following it is most likely due to a bug
in the compiler:
<pre>boost\boost\python\detail\invoke.hpp(76):
error C2064: term does not evaluate to a function taking 2 arguments"</pre>
This message is triggered by code like the following:
<pre>#include &lt;boost/python.hpp&gt;
using namespace boost::python;
class FXThread
{
public:
bool setAutoDelete(bool doso) throw();
};
void Export_FXThread()
{
class_< FXThread >("FXThread")
.def("setAutoDelete", &amp;FXThread::setAutoDelete)
;
}
</pre>
The bug is related to the <code>throw()</code> modifier.
As a workaround cast off the modifier. E.g.:
<pre>
.def("setAutoDelete", (bool (FXThread::*)(bool)) &amp;FXThread::setAutoDelete)</pre>
<p>(The bug has been reported to Microsoft.)</p>
<hr>
<h2><a name="voidptr"></a>How do I handle <tt>void *</tt> conversion?</h2>
<font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
For several reasons Boost.Python does not support <tt>void *</tt> as
an argument or as a return value. However, it is possible to wrap
functions with <tt>void *</tt> arguments or return values using
thin wrappers and the <i>opaque pointer</i> facility. E.g.:
<pre>// Declare the following in each translation unit
struct void_; // Deliberately do not define
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(void_);
void *foo(int par1, void *par2);
void_ *foo_wrapper(int par1, void_ *par2)
{
return (void_ *) foo(par1, par2);
}
...
BOOST_PYTHON_MODULE(bar)
{
def("foo", &amp;foo_wrapper);
}</pre>
<hr>
<h2><a name="custom_string"></a>How can I automatically
convert my custom string type to and from a Python string?</h2>
<font size="-1"><i>Ralf W. Grosse-Kunstleve provides these
notes:</i></font><p>
Below is a small, self-contained demo extension module that shows
how to do this. Here is the corresponding trivial test:
<pre>import custom_string
assert custom_string.hello() == "Hello world."
assert custom_string.size("california") == 10</pre>
If you look at the code you will find:
<ul>
<li>A custom <tt>to_python</tt> converter (easy):
<tt>custom_string_to_python_str</tt>
<li>A custom lvalue converter (needs more code):
<tt>custom_string_from_python_str</tt>
</ul>
The custom converters are registered in the global Boost.Python
registry near the top of the module initialization function. Once
flow control has passed through the registration code the automatic
conversions from and to Python strings will work in any module
imported in the same process.
<pre>#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/def.hpp&gt;
#include &lt;boost/python/to_python_converter.hpp&gt;
namespace sandbox { namespace {
class custom_string
{
public:
custom_string() {}
custom_string(std::string const&amp; value) : value_(value) {}
std::string const&amp; value() const { return value_; }
private:
std::string value_;
};
struct custom_string_to_python_str
{
static PyObject* convert(custom_string const&amp; s)
{
return boost::python::incref(boost::python::object(s.value()).ptr());
}
};
struct custom_string_from_python_str
{
custom_string_from_python_str()
{
boost::python::converter::registry::push_back(
&amp;convertible,
&amp;construct,
boost::python::type_id&lt;custom_string&gt;());
}
static void* convertible(PyObject* obj_ptr)
{
if (!PyString_Check(obj_ptr)) return 0;
return obj_ptr;
}
static void construct(
PyObject* obj_ptr,
boost::python::converter::rvalue_from_python_stage1_data* data)
{
const char* value = PyString_AsString(obj_ptr);
if (value == 0) boost::python::throw_error_already_set();
void* storage = (
(boost::python::converter::rvalue_from_python_storage&lt;custom_string&gt;*)
data)-&gt;storage.bytes;
new (storage) custom_string(value);
data-&gt;convertible = storage;
}
};
custom_string hello() { return custom_string(&quot;Hello world.&quot;); }
std::size_t size(custom_string const&amp; s) { return s.value().size(); }
void init_module()
{
using namespace boost::python;
boost::python::to_python_converter&lt;
custom_string,
custom_string_to_python_str&gt;();
custom_string_from_python_str();
def(&quot;hello&quot;, hello);
def(&quot;size&quot;, size);
}
}} // namespace sandbox::&lt;anonymous&gt;
BOOST_PYTHON_MODULE(custom_string)
{
sandbox::init_module();
}</pre>
<hr>
<h2><a name="topythonconversionfailed"></a
>Why is my automatic to-python conversion not being found?</h2>
<font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
If you define custom converters similar to the ones
shown above the <tt>def_readonly()</tt> and <tt>def_readwrite()</tt>
member functions provided by <tt>boost::python::class_</tt> for
direct access to your member data will not work as expected.
This is because <tt>def_readonly("bar",&nbsp;&amp;foo::bar)</tt> is
equivalent to:
<pre>.add_property("bar", make_getter(&amp;foo::bar, return_internal_reference()))</pre>
Similarly, <tt>def_readwrite("bar",&nbsp;&amp;foo::bar)</tt> is
equivalent to:
<pre>.add_property("bar", make_getter(&amp;foo::bar, return_internal_reference()),
make_setter(&amp;foo::bar, return_internal_reference())</pre>
In order to define return value policies compatible with the
custom conversions replace <tt>def_readonly()</tt> and
<tt>def_readwrite()</tt> by <tt>add_property()</tt>. E.g.:
<pre>.add_property("bar", make_getter(&amp;foo::bar, return_value_policy&lt;return_by_value&gt;()),
make_setter(&amp;foo::bar, return_value_policy&lt;return_by_value&gt;()))</pre>
<hr>
<h2><a name="threadsupport"></a
>Is Boost.Python thread-aware/compatible with multiple interpreters?</h2>
<font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
The quick answer to this is: no.</p>
<p>
The longer answer is that it can be patched to be so, but it's
complex. You will need to add custom lock/unlock wrapping of every
time your code enters Boost.Python (particularly every virtual
function override) plus heavily modify
<tt>boost/python/detail/invoke.hpp</tt> with custom unlock/lock
wrapping of every time Boost.Python enters your code. You must
furthermore take care to <i>not</i> unlock/lock when Boost.Python
is invoking iterator changes via <tt>invoke.hpp</tt>.</p>
<p>
There is a patched <tt>invoke.hpp</tt> posted on the C++-SIG
mailing list archives and you can find a real implementation of all
the machinery necessary to fully implement this in the TnFOX
project at <a href="http://sourceforge.net/projects/tnfox/"> this
SourceForge project location</a>.</p>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2002
28 January, 2004
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
Reserved.</i></p>
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002-2003. All
Rights Reserved.</i></p>
</body>
</html>

View File

@@ -20,7 +20,7 @@
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 class="c1">Boost.Python</h1>
<h1 class="c1"><a href="../index.html">Boost.Python</a></h1>
<h2 class="c2">February 2002 Progress Report</h2>
</table>
@@ -356,8 +356,8 @@
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
4 April, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p class="c3">&copy; Copyright <a href=

View File

@@ -13,7 +13,7 @@
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/from_python.hpp&gt;</h2>
</table>
@@ -71,9 +71,8 @@ namespace boost { namespace python
{
template &lt;class T&gt;
struct from_python : private <a href=
"../../../utility/utility.htm#Class noncopyable">boost::noncopyable</a> // Exposition only.
// from_python&lt;T&gt; meets the <a href=
"NonCopyable.html">NonCopyable</a> requirements
"../../../utility/utility.htm#Class_noncopyable">boost::noncopyable</a> // Exposition only.
// from_python&lt;T&gt; meets the NonCopyable requirements
{
from_python(PyObject*);
bool convertible() const;
@@ -157,8 +156,8 @@ std::size_t length_if_string(PyObject* p)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2001
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave

View File

@@ -14,7 +14,7 @@
span.c3 {color: #ff0000}
h2.c2 {text-align: center}
h1.c1 {text-align: center}
</style>
</style>
</head>
<body>
@@ -27,7 +27,7 @@
</td>
<td valign="top">
<h1 class="c1">Boost.Python</h1>
<h1 class="c1"><a href="../index.html">Boost.Python</a></h1>
<h2 class="c2">Header &lt;boost/python/handle.hpp&gt;</h2>
</td>
@@ -74,7 +74,6 @@
<dt><a href="#allow_null-spec"><code>allow_null</code></a></dt>
</dl>
</dd>
</dl>
<hr>
@@ -91,13 +90,12 @@
<p><code>handle</code> is a smart pointer to a Python object type; it
holds a pointer of type <code>T*</code>, where T is its template
parameter. <code>T</code> must be either a type derived from
<code>PyObject</code> or a <a href="definitions.html#POD">POD</a>
type whose initial <code>sizeof(PyObject)</code> bytes are
layout-compatible with <code>PyObject</code>. Use
<code>handle&lt;&gt;</code> at the boundary between tehe
Python/'C' API and high-level code; prefer <code><a
<code>PyObject</code> or a <a href="definitions.html#POD">POD</a> type
whose initial <code>sizeof(PyObject)</code> bytes are layout-compatible
with <code>PyObject</code>. Use <code>handle&lt;&gt;</code> at the
boundary between the Python/'C' API and high-level code; prefer <code><a
href="object.html#object-spec">object</a></code> for a generalized
interface to Python objects.
interface to Python objects.</p>
<p><a name="upcast"></a>In this document, the term "upcast" refers to an
operation which converts a pointer <code>Y*</code> to a base class
@@ -154,6 +152,7 @@ namespace boost { namespace python
T* operator-&gt; () const;
T&amp; operator* () const;
T* get() const;
void reset();
T* release();
operator bool_type() const; // never throws
@@ -173,7 +172,8 @@ virtual ~handle();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> <code>Py_XDECREF(m_p)</code></dt>
<dt><b>Effects:</b>
<code>Py_XDECREF(</code><i>upcast</i><code>&lt;PyObject*&gt;(m_p))</code></dt>
</dl>
<pre>
template &lt;class Y&gt;
@@ -181,7 +181,9 @@ explicit handle(detail::borrowed&lt;null_ok&lt;Y&gt; &gt;* p);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b> <code>Py_XDECREF(m_p)</code></dt>
<dt><b>Effects:</b>
<code>Py_XINCREF(</code><i>upcast</i><code>&lt;PyObject*&gt;(p));
m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(p);</code></dt>
</dl>
<pre>
template &lt;class Y&gt;
@@ -190,7 +192,8 @@ explicit handle(null_ok&lt;detail::borrowed&lt;Y&gt; &gt;* p);
<dl class="function-semantics">
<dt><b>Effects:</b>
<code>m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(p);</code></dt>
<code>Py_XINCREF(</code><i>upcast</i><code>&lt;PyObject*&gt;(p));
m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(p);</code></dt>
</dl>
<pre>
template &lt;class Y&gt;
@@ -199,7 +202,8 @@ explicit handle(detail::borrowed&lt;Y&gt;* p);
<dl class="function-semantics">
<dt><b>Effects:</b>
<code>m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(<a href=
<code>Py_XINCREF(</code><i>upcast</i><code>&lt;PyObject*&gt;(p));
m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(<a href=
"errors.html#expect_non_null-spec">expect_non_null</a>(p));</code></dt>
</dl>
<pre>
@@ -209,7 +213,7 @@ explicit handle(null_ok&lt;Y&gt;* p);
<dl class="function-semantics">
<dt><b>Effects:</b>
<code>Py_XINCREF(p);&nbsp;m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(p);</code></dt>
<code>m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(p);</code></dt>
</dl>
<pre>
template &lt;class Y&gt;
@@ -218,8 +222,7 @@ explicit handle(Y* p);
<dl class="function-semantics">
<dt><b>Effects:</b>
<code>Py_XINCREF(p);&nbsp;m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(<a
href=
<code>m_p&nbsp;=&nbsp;</code><i>upcast</i><code>&lt;T*&gt;(<a href=
"errors.html#expect_non_null-spec">expect_non_null</a>(p));</code></dt>
</dl>
<pre>
@@ -237,7 +240,7 @@ handle(handle const&amp; r);
<dl class="function-semantics">
<dt><b>Effects:</b>
<code>m_p&nbsp;=&nbsp;r.m_p;&nbsp;Py_XINCREF(m_p);</code></dt>
<code>m_p&nbsp;=&nbsp;r.m_p;&nbsp;Py_XINCREF(</code><i>upcast</i><code>&lt;PyObject*&gt;(m_p));</code></dt>
</dl>
<h4><a name="handle-spec-modifiers">Class <code>handle</code>
@@ -250,7 +253,8 @@ handle&amp; operator=(handle&lt;Y&gt; const &amp; r); // never throws
<dl class="function-semantics">
<dt><b>Effects:</b>
<code>Py_XINCREF(r.m_p);&nbsp;Py_XDECREF(m_p);&nbsp;m_p&nbsp;=&nbsp;r.m_p;</code></dt>
<code>Py_XINCREF(</code><i>upcast</i><code>&lt;PyObject*&gt;(r.m_p));&nbsp;Py_XDECREF(</code><i>
upcast</i><code>&lt;PyObject*&gt;(m_p));&nbsp;m_p&nbsp;=&nbsp;r.m_p;</code></dt>
</dl>
<pre>
T* release();
@@ -260,6 +264,14 @@ T* release();
<dt><b>Effects:</b> <code>T* x = m_p;&nbsp;m_p&nbsp;=&nbsp;0;return
x;</code></dt>
</dl>
<pre>
void reset();
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
<code>*this&nbsp;=&nbsp;handle&lt;T&gt;();</code></dt>
</dl>
<h4><a name="handle-spec-observers">Class <code>handle</code>
observers</a></h4>
@@ -291,27 +303,26 @@ operator bool_type() const; // never throws
<h3><a name="borrowed-spec"></a><code>borrowed</code></h3>
<pre>
template <class T>
detail::borrowed<T>* borrowed(T* p)
template &lt;class T&gt;
detail::borrowed&lt;T&gt;* borrowed(T* p)
{
return (detail::borrowed<T>*)p;
return (detail::borrowed&lt;T&gt;*)p;
}
</pre>
<h3><a name="allow_null-spec"></a><code>allow_null</code></h3>
<pre>
template <class T>
null_ok<T>* allow_null(T* p)
template &lt;class T&gt;
null_ok&lt;T&gt;* allow_null(T* p)
{
return (null_ok<T>*)p;
return (null_ok&lt;T&gt;*)p;
}
</pre>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
03 October, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p class="c4">&copy; Copyright <a href=

View File

@@ -26,7 +26,7 @@
</td>
<td valign="top">
<h1 class="c1">Boost.Python</h1>
<h1 class="c1"><a href="../index.html">Boost.Python</a></h1>
<h2 class="c2">Header
&lt;boost/python/has_back_reference.hpp&gt;</h2>
@@ -202,8 +202,8 @@ BOOST_PYTHON_MODULE(back_references)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
29 September, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p class="c3">&copy; Copyright <a href=

View File

@@ -13,7 +13,7 @@
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;{{header}}&gt;</h2>
</table>
@@ -279,8 +279,8 @@ namespace boost
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
05 November, 2001
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/implicit.hpp&gt;</h2>
</td>
@@ -149,8 +149,8 @@ BOOST_PYTHON_MODULE(implicit_ext)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
29 September, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -10,7 +10,7 @@
</head>
<body>
Automatic redirection failed, please go to <a href=
Loading index page; if nothing happens, please go to <a href=
"../index.html">../index.html</a>.
</body>
</html>

636
doc/v2/indexing.html Normal file
View File

@@ -0,0 +1,636 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Windows (vers 1st February 2003), see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>
Indexing Support
</title>
</head>
<body>
<table border="0" cellpadding="7" cellspacing="0" width="100%"
summary="header">
<tr>
<td valign="top" width="300">
<h3>
<a href="../../../../index.htm"><img height="86" width="277"
alt="C++ Boost" src="../../../../c++boost.gif" border=
"0"></a>
</h3>
</td>
<td valign="top">
<h1 align="center">
<a href="../index.html">Boost.Python</a>
</h1>
<h2> Headers &lt;boost/python/indexing/indexing_suite.hpp&gt;<br>
&lt;boost/python/indexing/vector_indexing_suite.hpp&gt;</h2>
</td>
</tr>
</table>
<hr>
<h2>
Contents
</h2>
<dl class="page-index">
<dt>
<a href="#introduction">Introduction</a>
</dt>
<dt>
<a href="#interface">Interface</a>
</dt>
<dd>
<dl class="page-index">
<dt>
<a href="#indexing_suite">indexing_suite</a>
</dt>
<dt>
<a href="#indexing_suite_subclasses">indexing_suite
sub-classes</a>
</dt>
<dd>
<dl class="page-index">
<dt>
<a href="#vector_indexing_suite">vector_indexing_suite</a>
</dt>
</dl>
</dd>
</dl>
</dd>
</dl>
<dl>
<dt>
<a href="#indexing_suite_class">indexing_suite class</a>
</dt>
<dt>
<a href="#vector_indexing_suite_class">vector_indexing_suite
class</a>
</dt>
</dl>
<hr>
<h2>
<a name="introduction" id="introduction"></a>Introduction
</h2>
<p>
Indexing is a Boost Python facility for easy exportation of indexable
C++ containers to Python. Indexable containers are containers that
allow random access through the operator[] (e.g. std::vector).
</p>
<p>
While Boost Python has all the facilities needed to expose indexable
C++ containers such as the ubiquitous std::vector to Python, the
procedure is not as straightforward as we'd like it to be. Python
containers do not map easily to C++ containers. Emulating Python
containers in C++ (see Python Reference Manual, <a href=
"http://www.python.org/doc/current/ref/sequence-types.html">Emulating
container types</a>) using Boost Python is non trivial. There are a lot
of issues to consider before we can map a C++ container to Python.
These involve implementing wrapper functions for the methods
<strong>__len__</strong>, <strong>__getitem__</strong>,
<strong>__setitem__</strong>, <strong>__delitem__,</strong>
<strong>__iter__</strong> and <strong>__contains</strong>.
</p>
<p>
The goals:
</p>
<ul>
<li>
<div>
Make indexable C++ containers behave exactly as one would expect a
Python container to behave.
</div>
</li>
<li>
Provide default reference semantics for container element indexing
(<tt>__getitem__</tt>) such that <tt>c[i]</tt> can be mutable.
Require:
<div>
<pre>
val = c[i]
c[i].m()
val == c[i]
</pre>
</div>where <tt>m</tt> is a non-const (mutating) member function
(method).
</li>
<li>
Return safe references from <tt>__getitem__</tt> such that subsequent
adds and deletes to and from the container will not result in
dangling references (will not crash Python).
</li>
<li>
Support slice indexes.
</li>
<li>
Accept Python container arguments (e.g. lists, tuples) wherever
appropriate.
</li>
<li>
Allow for extensibility through re-definable policy classes.
</li>
<li>
Provide predefined support for the most common STL and STL like
indexable containers.
</li>
</ul>
<hr>
<h2> <a name="interface"></a>The Boost.Python Indexing Interface</h2>
<h3> <a name="indexing_suite"></a>indexing_suite [ Header &lt;boost/python/indexing/indexing_suite.hpp&gt;
]</h3>
<p>
The <tt>indexing_suite</tt> class is the base protocol class for the
management of C++ containers intended to be integrated to Python. The
objective is make a C++ container look and feel and behave exactly as
we'd expect a Python container. The class automatically wraps these
special Python methods (taken from the Python reference: <a href=
"http://www.python.org/doc/current/ref/sequence-types.html">Emulating
container types</a>):
</p>
<dl>
<dd>
<dl>
<dt>
<b><a name="l2h-126"><tt class=
"method">__len__</tt></a></b>(<var>self</var>)
</dt>
<dd>
Called to implement the built-in function <tt class=
"function">len()</tt><a name="l2h-134">&nbsp;</a> Should return
the length of the object, an integer <code>&gt;=</code> 0. Also,
an object that doesn't define a <tt class=
"method">__nonzero__()</tt> method and whose <tt class=
"method">__len__()</tt> method returns zero is considered to be
false in a Boolean context. <a name="l2h-128">&nbsp;</a>
</dd>
</dl>
<dl>
<dt>
<b><a name="l2h-129"><tt class=
"method">__getitem__</tt></a></b>(<var>self, key</var>)
</dt>
<dd>
Called to implement evaluation of
<code><var>self</var>[<var>key</var>]</code>. For sequence types,
the accepted keys should be integers and slice
objects.<a name="l2h-135">&nbsp;</a> Note that the special
interpretation of negative indexes (if the class wishes to
emulate a sequence type) is up to the <tt class=
"method">__getitem__()</tt> method. If <var>key</var> is of
an inappropriate type, <tt class="exception">TypeError</tt>
may be raised; if of a value outside the set of indexes for
the sequence (after any special interpretation of negative
values), <tt class="exception">IndexError</tt> should be
raised. <span class="note"><b class="label">Note:</b>
<tt class="keyword">for</tt> loops expect that an <tt class=
"exception">IndexError</tt> will be raised for illegal
indexes to allow proper detection of the end of the
sequence.</span>
</dd>
</dl>
<dl>
<dt>
<b><a name="l2h-130"><tt class=
"method">__setitem__</tt></a></b>(<var>self, key, value</var>)
</dt>
<dd>
Called to implement assignment to
<code><var>self</var>[<var>key</var>]</code>. Same note as for
<tt class="method">__getitem__()</tt>. This should only be
implemented for mappings if the objects support changes to the
values for keys, or if new keys can be added, or for sequences if
elements can be replaced. The same exceptions should be raised
for improper <var>key</var> values as for the <tt class=
"method">__getitem__()</tt> method.
</dd>
</dl>
<dl>
<dt>
<b><a name="l2h-131"><tt class=
"method">__delitem__</tt></a></b>(<var>self, key</var>)
</dt>
<dd>
Called to implement deletion of
<code><var>self</var>[<var>key</var>]</code>. Same note as for
<tt class="method">__getitem__()</tt>. This should only be
implemented for mappings if the objects support removal of keys,
or for sequences if elements can be removed from the sequence.
The same exceptions should be raised for improper <var>key</var>
values as for the <tt class="method">__getitem__()</tt> method.
</dd>
</dl>
<dl>
<dt>
<b><a name="l2h-132"><tt class=
"method">__iter__</tt></a></b>(<var>self</var>)
</dt>
<dd>
This method is called when an iterator is required for a
container. This method should return a new iterator object that
can iterate over all the objects in the container. For mappings,
it should iterate over the keys of the container, and should also
be made available as the method <tt class=
"method">iterkeys()</tt>.
<p>
Iterator objects also need to implement this method; they are
required to return themselves. For more information on iterator
objects, see ``<a class="ulink" href=
"http://www.python.org/doc/current/lib/typeiter.html">Iterator
Types</a>'' in the <em class="citetitle"><a href=
"http://www.python.org/doc/current/lib/lib.html" title=
"Python Library Reference">Python Library Reference</a></em>.
</p>
</dd>
</dl>
<dl>
<dt>
<b><a name="l2h-133"><tt class=
"method">__contains__</tt></a></b>(<var>self, item</var>)
</dt>
<dd>
Called to implement membership test operators. Should return true
if <var>item</var> is in <var>self</var>, false otherwise. For
mapping objects, this should consider the keys of the mapping
rather than the values or the key-item pairs.
</dd>
</dl>
</dd>
</dl>
<h3> <a name="indexing_suite_subclasses"></a>indexing_suite sub-classes</h3>
<p>
The <tt>indexing_suite</tt> is not meant to be used as is. A couple of
policy functions must be supplied by subclasses of
<tt>indexing_suite</tt>. However, a set of <tt>indexing_suite</tt>
subclasses for the standard indexable STL containers will be provided,
In most cases, we can simply use the available predefined suites. In
some cases, we can refine the predefined suites to suit our needs.
</p>
<h3> <a name="vector_indexing_suite"></a>vector_indexing_suite [ Header &lt;boost/python/indexing/vector_indexing_suite.hpp&gt;
] </h3>
<p>
The <tt>vector_indexing_suite</tt> class is a predefined
<tt>indexing_suite</tt> derived class designed to wrap
<tt>std::vector</tt> (and <tt>std::vector</tt> like [i.e. a class with
std::vector interface]) classes (currently, this is the only predefined
suite available). It provides all the policies required by the
<tt>indexing_suite</tt>.
</p>
<p>
Example usage:
</p>
<pre>
class X {...};
...
class_&lt;std::vector&lt;X&gt; &gt;("XVec")
.def(vector_indexing_suite&lt;std::vector&lt;X&gt; &gt;())
;
</pre>
<p>
<tt>XVec</tt> is now a full-fledged Python container (see the
<a href="../../test/vector_indexing_suite.cpp">example in full</a>,
along with its <a href="../../test/vector_indexing_suite.py">python
test</a>).
</p>
<hr>
<h2>
<a name="indexing_suite_class"></a>indexing_suite class
</h2>
<h3>
<br>
<tt>indexing_suite&lt;<br>
class Container<br>
, class DerivedPolicies<font color="#007F00"><br>
</font></tt> <tt>,
bool NoProxy<br>
, class Element<br>
, class Key<br>
, class Index</tt>
</h3>
<table width="100%" border="1">
<tr>
<td>
<strong>Template Parameter</strong><br>
</td>
<td>
<strong>Requirements</strong>
</td>
<td>
<strong>Semantics</strong>
</td>
<td>
<strong>Default</strong>
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>Container</tt></font>
</td>
<td>
A class type
</td>
<td>
The container type to be wrapped to Python.
</td>
<td>&nbsp;
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>DerivedPolicies</tt></font>
</td>
<td>
A subclass of indexing_suite
</td>
<td>
Derived classes provide the policy hooks. See <a href=
"#DerivedPolicies">DerivedPolicies</a> below.
</td>
<td>&nbsp;
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>NoProxy</tt></font>
</td>
<td>
A boolean
</td>
<td>
By default indexed elements have Python reference semantics and are
returned by proxy. This can be disabled by supplying
<strong>true</strong> in the <tt>NoProxy</tt> template parameter.
</td>
<td>
false
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>Element</tt></font>
</td>
<td>&nbsp;
</td>
<td>
The container's element type.
</td>
<td>
<tt>Container::value_type</tt>
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>Key</tt></font>
</td>
<td>&nbsp;
</td>
<td>
The container's key type.
</td>
<td>
<tt>Container::value_type</tt>
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>Index</tt></font>
</td>
<td>&nbsp;
</td>
<td>
The container's index type.
</td>
<td>
<tt>Container::size_type</tt>
</td>
</tr>
</table>
<pre>
template &lt;<br> class Container
, class DerivedPolicies
, bool NoProxy = false
, class Element = typename Container::value_type
, class Key = typename Container::value_type
, class Index = typename Container::size_type
&gt;<br> class indexing_suite
: unspecified
{
public:
indexing_suite(); // default constructor
}
</pre>
<h2>
<tt><a name="DerivedPolicies"></a>DerivedPolicies</tt>
</h2>
<dl>
<dd>
Derived classes provide the hooks needed by
the<tt>indexing_suite:</tt>
</dd>
</dl>
<pre>
static element_type&amp;
get_item(Container&amp; container, index_type i);
static object
get_slice(Container&amp; container, index_type from, index_type to);
static void
set_item(Container&amp; container, index_type i, element_type const&amp; v);
static void
set_slice(
Container&amp; container, index_type from,
index_type to, element_type const&amp; v
);
template &lt;class Iter&gt;
static void<br> set_slice(Container&amp; container, index_type from,
index_type to, Iter first, Iter last
);
static void
delete_item(Container&amp; container, index_type i);
static void
delete_slice(Container&amp; container, index_type from, index_type to);
static size_t
size(Container&amp; container);
template &lt;class T&gt;
static bool
contains(Container&amp; container, T const&amp; val);
static index_type
convert_index(Container&amp; container, PyObject* i);
static index_type
adjust_index(index_type current, index_type from,
index_type to, size_type len
);
</pre>
<blockquote>
<p>
Most of these policies are self explanatory. <tt>However,
<strong>convert_index</strong></tt> and
<tt><strong>adjust_index</strong></tt> deserve some explanation.
</p>
<p>
<strong><tt>convert_index</tt></strong> converts a Python index into
a C++ index that the container can handle. For instance, negative
indexes in Python, by convention, start counting from the right(e.g.
<tt>C[-1]</tt> indexes the rightmost element in <tt>C</tt>).
<strong><tt>convert_index</tt></strong> should handle the necessary
conversion for the C++ container (e.g. convert <tt>-1</tt> to
<tt>C.size()-1</tt>). <tt><strong>convert_index</strong></tt> should
also be able to convert the type of the index (A dynamic Python type)
to the actual type that the C++ container expects.
</p>
<p>
When a container expands or contracts, held indexes to its elements
must be adjusted to follow the movement of data. For instance, if we
erase 3 elements, starting from index 0 from a 5 element vector, what
used to be at index 4 will now be at index 1:
</p>
<pre>
[a][b][c][d][e] ---&gt; [d][e]
^ ^
4 1
</pre>
<p>
<strong><tt>adjust_index</tt></strong> takes care of the adjustment.
Given a current index, the function should return the adjusted index
when data in the container at index <tt>from</tt>..<tt>to</tt> is
replaced by <tt>len</tt> elements.
</p>
</blockquote>
<div>
<hr>
<h2>
<a name="vector_indexing_suite_class"></a>vector_indexing_suite class
</h2>
<h3>
Class template <tt><br>
vector_indexing_suite&lt;<br>
class <font color="#007F00">Container</font><br>
, bool <font color="#007F00">NoProxy</font><br>
, class <font color="#007F00">DerivedPolicies</font>&gt;</tt>
</h3>
<table width="100%" border="1">
<tr>
<td>
<strong>Template Parameter</strong><br>
</td>
<td>
<strong>Requirements</strong>
</td>
<td>
<strong>Semantics</strong>
</td>
<td>
<strong>Default</strong>
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>Container</tt></font>
</td>
<td>
A class type
</td>
<td>
The container type to be wrapped to Python.
</td>
<td>&nbsp;
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>NoProxy</tt></font>
</td>
<td>
A boolean
</td>
<td>
By default indexed elements have Python reference semantics and
are returned by proxy. This can be disabled by supplying
<strong>true</strong> in the <tt>NoProxy</tt> template parameter.
</td>
<td>
false
</td>
</tr>
<tr>
<td>
<font color="#007F00"><tt>DerivedPolicies</tt></font>
</td>
<td>
A subclass of indexing_suite
</td>
<td>
The <tt>vector_indexing_suite</tt> may still be derived to
further tweak any of the predefined policies. Static polymorphism
through CRTP (James Coplien. "Curiously Recurring Template
Pattern". C++ Report, Feb. 1995) enables the base
<tt>indexing_suite</tt> class to call policy function of the most
derived class
</td>
<td>&nbsp;
</td>
</tr>
</table>
<pre>
template &lt;<br> class Container,<br> bool NoProxy = false,<br> class DerivedPolicies = unspecified_default<br> class vector_indexing_suite<br> : public indexing_suite&lt;Container, DerivedPolicies, NoProxy&gt;<br> {<br> public:<br><br> typedef typename Container::value_type element_type;<br> typedef typename Container::value_type key_type;<br> typedef typename Container::size_type index_type;<br> typedef typename Container::size_type size_type;<br> typedef typename Container::difference_type difference_type;<br> <br> static element_type&amp;<br> get_item(Container&amp; container, index_type i);
static object
get_slice(Container&amp; container, index_type from, index_type to);
static void<br> set_item(Container&amp; container, index_type i, element_type const&amp; v);
static void
set_slice(Container&amp; container, index_type from,
index_type to, element_type const&amp; v);
template &lt;class Iter&gt;<br> static void<br> set_slice(Container&amp; container, index_type from,<br> index_type to, Iter first, Iter last);
static void
delete_item(Container&amp; container, index_type i);
static void
delete_slice(Container&amp; container, index_type from, index_type to);<br>
static size_t
size(Container&amp; container);
static bool
contains(Container&amp; container, key_type const&amp; key);
static index_type
convert_index(Container&amp; container, PyObject* i);
static index_type
adjust_index(index_type current, index_type from,
index_type to, size_type len);
};
</pre>
<hr>
&copy; Copyright Joel de Guzman 2003. 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.
</div>
</body>
</html>

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Headers &lt;boost/python/init.hpp&gt;</h2>
</td>
@@ -237,8 +237,8 @@ class_&lt;X&gt;("X", "This is X's docstring.",
<hr>
Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
1 October, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href=

View File

@@ -22,7 +22,7 @@
"0"></a></h3>
<td valign="top">
<h1 class="c1">Boost.Python</h1>
<h1 class="c1"><a href="../index.html">Boost.Python</a></h1>
<h2 class="c2">Header &lt;boost/python/instance_holder.hpp&gt;</h2>
</table>
@@ -97,7 +97,7 @@
<pre>
namespace boost { namespace python
{
class instance_holder : <a href="../../../utility/utility.htm#Class noncopyable">noncopyable</a>
class instance_holder : <a href="../../../utility/utility.htm#Class_noncopyable">noncopyable</a>
{
public:
// destructor
@@ -199,8 +199,8 @@ struct pointer_holder : instance_holder
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
29 May, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p class="c4">&copy; Copyright <a href=

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/iterator.hpp&gt;</h2>
</td>
@@ -383,8 +383,8 @@ BOOST_PYTHON_MODULE(demo)
<dd>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
29 September, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/list.hpp&gt;</h2>
</td>

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/long.hpp&gt;</h2>
</td>

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/lvalue_from_pytype.hpp&gt;</h2>
@@ -238,8 +238,10 @@ static MemberType&amp; execute(InstanceType&amp; c);
<h3>C++ module definition</h3>
<pre>
#include &lt;boost/python/reference.hpp&gt;
#include &lt;boost/python/module.hpp&gt;
#include &lt;boost/python/handle.hpp&gt;
#include &lt;boost/python/borrowed.hpp&gt;
#include &lt;boost/python/lvalue_from_pytype.hpp&gt;
// definition lifted from the Python docs
typedef struct {
@@ -247,7 +249,7 @@ typedef struct {
} noddy_NoddyObject;
using namespace boost::python;
static reference&lt;PyObject&gt; cache;
static handle&lt;noddy_NoddyObject&gt; cache;
bool is_cached(noddy_NoddyObject* x)
{
@@ -256,7 +258,7 @@ bool is_cached(noddy_NoddyObject* x)
void set_cache(noddy_NoddyObject* x)
{
cache.reset((PyObject*)x, ref::increment_count);
cache = handle&lt;noddy_NoddyObject&gt;(borrowed(x));
}
BOOST_PYTHON_MODULE(noddy_cache)
@@ -285,8 +287,8 @@ BOOST_PYTHON_MODULE(noddy_cache)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
29 September, 2001
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
20 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/make_function.hpp&gt;</h2>
@@ -66,9 +66,13 @@ template &lt;class F, class Policies&gt;
<a href=
"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies)
template &lt;class F, class Policies, class Keywords&gt;
template &lt;class F, class Policies, class KeywordsOrSignature&gt;
<a href=
"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies, Keywords const&amp; keywords)
"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies, KeywordsOrSignature const&amp; ks)
template &lt;class F, class Policies, class Keywords, class Signature&gt;
<a href=
"object.html#object-spec">object</a> make_function(F f, Policies const&amp; policies, Keywords const&amp; kw, Signature const&amp; sig)
</pre>
<dl class="function-semantics">
@@ -82,19 +86,41 @@ template &lt;class F, class Policies, class Keywords&gt;
<dt><b>Effects:</b> Creates a Python callable object which, when called
from Python, converts its arguments to C++ and calls <code>f</code>. If
<code>F</code> is a pointer-to-member-function type, the target object
of the function call (<code>*this</code>) will be taken from the first
Python argument, and subsequent Python arguments will be used as the
arguments to <code>f</code>. If <code>policies</code> are supplied, it
<code>F</code> is a pointer-to-member-function type, the target
object of the function call (<code>*this</code>) will be taken
from the first Python argument, and subsequent Python arguments
will be used as the arguments
to <code>f</code>. <ul>
<li> If <code>policies</code> are supplied, it
will be applied to the function as described <a href=
"CallPolicies.html">here</a>. If <code>keywords</code> are
"CallPolicies.html">here</a>.
<li>If <code>keywords</code> are
supplied, the keywords will be applied in order to the final
arguments of the resulting function.</dt>
arguments of the resulting function.
<li>If <code>Signature</code>
is supplied, it should be an instance of an <a
href="../../../mpl/doc/ref/Sequence.html">MPL front-extensible
sequence</a> representing the function's return type followed by
its argument types. Pass a <code>Signature</code> when wrapping
function object types whose signatures can't be deduced, or when
you wish to override the types which will be passed to the
wrapped function.
</ul></dt>
<dt><b>Returns:</b> An instance of <a href=
"object.html#object-spec">object</a> which holds the new Python
callable object.</dt>
<dt><b>Caveats:</b> An argument of pointer type may
be <code>0</code> if <code>None</code> is passed from Python.
An argument type which is a constant reference may refer to a
temporary which was created from the Python object for just the
duration of the call to the wrapped function, for example
a <code>std::vector</code> conjured up by the conversion process
from a Python list. Use a non-<code>const</code> reference
argument when a persistent lvalue is required.
</dl>
<pre>
<a name=
"make_constructor-spec"></a>template &lt;class T, class ArgList, class Generator&gt;
@@ -109,7 +135,7 @@ template &lt;class ArgList, class Generator, class Policies&gt;
<dt><b>Requires:</b> <code>T</code> is a class type.
<code>Policies</code> is a model of <a href=
"CallPolicies.html">CallPolicies</a>. <code>ArgList</code> is an <a
href="../../../mpl/doc/Sequences.html">MPL sequence</a> of C++ argument
href="../../../mpl/doc/ref/Sequences.html">MPL sequence</a> of C++ argument
types (<i>A1,&nbsp;A2,...&nbsp;AN</i>) such that if
<code>a1,&nbsp;a2</code>...&nbsp;<code>aN</code> are objects of type
<i>A1,&nbsp;A2,...&nbsp;AN</i> respectively, the expression <code>new
@@ -170,8 +196,8 @@ BOOST_PYTHON_MODULE(make_function_test)
<p>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
29 September 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -20,7 +20,7 @@
</td>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header
&lt;boost/python/manage_new_object.hpp&gt;</h2>
@@ -131,8 +131,8 @@ BOOST_PYTHON_MODULE(my_module)
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
29 September 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
</p>
<p><i>&copy; Copyright <a href=

View File

@@ -13,7 +13,7 @@
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
<h2 align="center">Header &lt;boost/python/module.hpp&gt;</h2>
</table>
@@ -99,8 +99,8 @@ RuntimeError: Unidentifiable C++ Exception
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
2 October, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
13 November, 2002
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave

Some files were not shown because too many files have changed in this diff Show More