Compare commits
1765 Commits
svn-branch
...
boost-1.43
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37731fce5b | ||
|
|
86db60255a | ||
|
|
37b45d2baf | ||
|
|
471be524f4 | ||
|
|
e485244886 | ||
|
|
b9cd3ff109 | ||
|
|
d804f1250e | ||
|
|
89100353db | ||
|
|
46be73387c | ||
|
|
d685a5e8c5 | ||
|
|
e80224b1ad | ||
|
|
03fdf5b992 | ||
|
|
73b4cd3325 | ||
|
|
f7d31f6ead | ||
|
|
47bb3f55a7 | ||
|
|
6296bd5bc4 | ||
|
|
217250f078 | ||
|
|
29152af56c | ||
|
|
19846f5d79 | ||
|
|
a1924a2a72 | ||
|
|
c205cd86c6 | ||
|
|
8d86dc199c | ||
|
|
55e9ff14a1 | ||
|
|
4fea58f634 | ||
|
|
694ae13063 | ||
|
|
5168895803 | ||
|
|
c8bf94663c | ||
|
|
928a9389ce | ||
|
|
7d22435994 | ||
|
|
96dd880146 | ||
|
|
63f8e9f3d7 | ||
|
|
d9b4ada654 | ||
|
|
f5df393360 | ||
|
|
bf33b54638 | ||
|
|
87451007b9 | ||
|
|
2392a6a3e2 | ||
|
|
6c1e7decfa | ||
|
|
2851325748 | ||
|
|
bd606e5017 | ||
|
|
a5706ec3b0 | ||
|
|
a346c577cf | ||
|
|
217e4ca8f8 | ||
|
|
f2f47f85c0 | ||
|
|
b130c93af6 | ||
|
|
13432b504f | ||
|
|
0739bb7df8 | ||
|
|
c253c5cc9c | ||
|
|
8f263e1fdb | ||
|
|
a6125a3632 | ||
|
|
a784bfc0f8 | ||
|
|
b8937d0bae | ||
|
|
4827ae73d5 | ||
|
|
8eddc7aa37 | ||
|
|
98a468dadc | ||
|
|
ea4e6c0a4c | ||
|
|
7cd7f6d8ee | ||
|
|
4c39e8c990 | ||
|
|
6c6f654fbe | ||
|
|
b7eaea096e | ||
|
|
904ae8604c | ||
|
|
44d53c448b | ||
|
|
e61401d27e | ||
|
|
be7ca7d269 | ||
|
|
47b4b4efbb | ||
|
|
4fa07f2b3d | ||
|
|
c880e7d69d | ||
|
|
c73ad50286 | ||
|
|
0910710ac4 | ||
|
|
04c528138b | ||
|
|
1b66cd9643 | ||
|
|
c2dd9fa833 | ||
|
|
b085121369 | ||
|
|
fa219bce9b | ||
|
|
10b85d67e7 | ||
|
|
ca91dc828e | ||
|
|
3a53c1dec0 | ||
|
|
da8e309957 | ||
|
|
2bd9141d4a | ||
|
|
c3bda6a903 | ||
|
|
d61909d3ea | ||
|
|
1755dad7e6 | ||
|
|
3b392c99be | ||
|
|
24ba93607b | ||
|
|
49d4aac8ec | ||
|
|
545be29ad3 | ||
|
|
8553c109c7 | ||
|
|
315c3d50ee | ||
|
|
d5219979a4 | ||
|
|
d42054f3a0 | ||
|
|
72b06e70ee | ||
|
|
375cc3aa93 | ||
|
|
4eb286a034 | ||
|
|
a824230155 | ||
|
|
1bc3750ab3 | ||
|
|
36abcee847 | ||
|
|
b8b7768eb7 | ||
|
|
7ad9dc6c64 | ||
|
|
decc34551a | ||
|
|
5acb44ede0 | ||
|
|
ef62f87963 | ||
|
|
b5c893381f | ||
|
|
815969bf8b | ||
|
|
0d57e9e808 | ||
|
|
7ba6a00617 | ||
|
|
e70bbe4791 | ||
|
|
7ff0f62729 | ||
|
|
95f0b39c90 | ||
|
|
23057688f9 | ||
|
|
029618f719 | ||
|
|
38f7a4e9b6 | ||
|
|
326c871224 | ||
|
|
924eeccd53 | ||
|
|
4a63cf4843 | ||
|
|
1d65b74273 | ||
|
|
3c1ae689a7 | ||
|
|
a99bd50e52 | ||
|
|
8b178594ff | ||
|
|
786aeef998 | ||
|
|
45e4cf506f | ||
|
|
8fb6e1f48d | ||
|
|
ecf70b05f2 | ||
|
|
c54acdb9db | ||
|
|
489dae2b58 | ||
|
|
f852ce6f7b | ||
|
|
e500919d25 | ||
|
|
7a645a6d8a | ||
|
|
fa2185e5ab | ||
|
|
5cc33461dd | ||
|
|
7b93f2fdc5 | ||
|
|
219743964d | ||
|
|
e7927ef4ea | ||
|
|
8c1f04bd4c | ||
|
|
136587c96f | ||
|
|
23664ec448 | ||
|
|
6b1a3c4489 | ||
|
|
fa4ebe5c53 | ||
|
|
28ef4a9e38 | ||
|
|
5d1053552c | ||
|
|
0a38ca1660 | ||
|
|
5791e3b58e | ||
|
|
2bfd2fa0fd | ||
|
|
0793267bf0 | ||
|
|
eca25c0b7d | ||
|
|
a8bad65556 | ||
|
|
6ef31ba33a | ||
|
|
c15216b385 | ||
|
|
a1ff35769b | ||
|
|
22e82ae30f | ||
|
|
2d117bc4ad | ||
|
|
6347ca8065 | ||
|
|
c39836ddc8 | ||
|
|
fb35a82bf1 | ||
|
|
44c5c18f45 | ||
|
|
e0cceeb88c | ||
|
|
4a5f6f2e24 | ||
|
|
8b1748fea0 | ||
|
|
82919f0d5c | ||
|
|
1f6ded7b4e | ||
|
|
a0d2873156 | ||
|
|
0519d54229 | ||
|
|
c181874335 | ||
|
|
203a42c35f | ||
|
|
8eba0eb25b | ||
|
|
152e76220a | ||
|
|
8897cc9ce6 | ||
|
|
335cd02c2d | ||
|
|
758d92b33e | ||
|
|
28eef45d28 | ||
|
|
d8790a34d3 | ||
|
|
3b058185c6 | ||
|
|
2261e7eedc | ||
|
|
19a196493f | ||
|
|
d10b5e8d1a | ||
|
|
1cacefc226 | ||
|
|
efcd2833f1 | ||
|
|
2f9323d9e9 | ||
|
|
8b2f4b4ce0 | ||
|
|
ab046dc634 | ||
|
|
ef3f9b15f0 | ||
|
|
68463e2fd2 | ||
|
|
f75eca94e0 | ||
|
|
a23030b83e | ||
|
|
321cf2502a | ||
|
|
4996f912b4 | ||
|
|
09e24cb17d | ||
|
|
ac32d13e10 | ||
|
|
b0496d1207 | ||
|
|
a076239fc8 | ||
|
|
7cf0f9090f | ||
|
|
479f068673 | ||
|
|
9b326f15fa | ||
|
|
f094a5b9eb | ||
|
|
4367850e5d | ||
|
|
f44a4d6468 | ||
|
|
5206dd55d2 | ||
|
|
988bf849a1 | ||
|
|
6fee43fc6f | ||
|
|
6ec4387ea1 | ||
|
|
e2f59ef548 | ||
|
|
92a6fafd20 | ||
|
|
4721f5f9af | ||
|
|
3864838da2 | ||
|
|
8e77df69d5 | ||
|
|
12770b03e8 | ||
|
|
c8a692b4b4 | ||
|
|
2571ebb0c2 | ||
|
|
283dbfb593 | ||
|
|
83f227034f | ||
|
|
c5f514a4e6 | ||
|
|
9fb15f631e | ||
|
|
3d8f4c90ba | ||
|
|
5597dcb321 | ||
|
|
ab2912e3c2 | ||
|
|
b705931ff0 | ||
|
|
2974286209 | ||
|
|
1cec514b39 | ||
|
|
8ecd49cbf0 | ||
|
|
67a7669ff4 | ||
|
|
e80545a7d3 | ||
|
|
6afe0d4732 | ||
|
|
f8280b0e1a | ||
|
|
aa20ce7d2c | ||
|
|
6074a23242 | ||
|
|
9ceac3ff8f | ||
|
|
126a3efb92 | ||
|
|
9205f507b0 | ||
|
|
bff975f08c | ||
|
|
262bcee750 | ||
|
|
a3f12b18b1 | ||
|
|
ad635ec2d1 | ||
|
|
affd36e857 | ||
|
|
332a45f333 | ||
|
|
6cc48f7e5d | ||
|
|
5b6192d738 | ||
|
|
980733a96d | ||
|
|
331209d8b5 | ||
|
|
9116cf382b | ||
|
|
8cc2b7a5df | ||
|
|
dab01ad668 | ||
|
|
1fca114f6a | ||
|
|
70ee460a14 | ||
|
|
07c95aea4e | ||
|
|
a3d8a384fa | ||
|
|
432d4782a5 | ||
|
|
424f5bdf31 | ||
|
|
13b16f9729 | ||
|
|
82563df3bf | ||
|
|
adb7b62a62 | ||
|
|
02c0b2b486 | ||
|
|
c876db8cae | ||
|
|
3ce88daa8b | ||
|
|
4cec6c4f2f | ||
|
|
e38bf06257 | ||
|
|
0deed1ff9b | ||
|
|
a05a0ae46b | ||
|
|
fe3906a7cb | ||
|
|
e5ed3a1c6c | ||
|
|
2bbff71109 | ||
|
|
c492551111 | ||
|
|
b217c4ffa8 | ||
|
|
96e9d6a872 | ||
|
|
fef288fed2 | ||
|
|
2fdb98079d | ||
|
|
bbabf21abf | ||
|
|
6d24977dd2 | ||
|
|
c2b5925600 | ||
|
|
91e76a296f | ||
|
|
e4eee902d4 | ||
|
|
db71f17dba | ||
|
|
b754037949 | ||
|
|
7bd76d869b | ||
|
|
c25967a094 | ||
|
|
bcb6370b0e | ||
|
|
17faf4504c | ||
|
|
53c335f106 | ||
|
|
cd8951439e | ||
|
|
0e5e2dc92e | ||
|
|
4d50bf0ad9 | ||
|
|
1cfa79554d | ||
|
|
567e620565 | ||
|
|
5933fdbf39 | ||
|
|
4c21a29a9f | ||
|
|
7c21f3b48d | ||
|
|
6f4167700c | ||
|
|
efae35bbd8 | ||
|
|
8dbd926d9e | ||
|
|
c6e658cfca | ||
|
|
b77dcf4bea | ||
|
|
1e3cfbca03 | ||
|
|
1ed231747b | ||
|
|
a926eaa86d | ||
|
|
acd8ec2c31 | ||
|
|
441a9dbea0 | ||
|
|
63e92c49df | ||
|
|
49dd8bcf51 | ||
|
|
942f4c4ffd | ||
|
|
43791f3a71 | ||
|
|
321bea59fb | ||
|
|
601fd16cba | ||
|
|
a9cddc10a9 | ||
|
|
03fc159aec | ||
|
|
59b596e1ee | ||
|
|
1fe6626edb | ||
|
|
fa8cffb3a2 | ||
|
|
11daf8dde8 | ||
|
|
0d6ac67c04 | ||
|
|
978dc88499 | ||
|
|
655868d803 | ||
|
|
92ff4ab76f | ||
|
|
48a6db6598 | ||
|
|
a97d050016 | ||
|
|
e888d8aa88 | ||
|
|
59ca82128a | ||
|
|
0620462efb | ||
|
|
f99f1e187c | ||
|
|
937a851baa | ||
|
|
8e396f8e91 | ||
|
|
bd74676685 | ||
|
|
70e012bc45 | ||
|
|
3bb3434a8d | ||
|
|
2121039a2b | ||
|
|
5bab5a2398 | ||
|
|
2ca8be0bb2 | ||
|
|
227448f061 | ||
|
|
0b026dc5a2 | ||
|
|
3ba268ed9c | ||
|
|
c4b09c7526 | ||
|
|
164e517a54 | ||
|
|
fd75e791a7 | ||
|
|
7eb9f910ba | ||
|
|
78cd3298aa | ||
|
|
2f5dfbb728 | ||
|
|
3750668aad | ||
|
|
dc2acc5bf5 | ||
|
|
f7db275bc4 | ||
|
|
7171a34364 | ||
|
|
f1260e6869 | ||
|
|
0b4f2bafe6 | ||
|
|
c5cf576deb | ||
|
|
bfd7f71601 | ||
|
|
87718f91ab | ||
|
|
3918395715 | ||
|
|
dec9c6d96e | ||
|
|
0c651a890c | ||
|
|
e00462992c | ||
|
|
951c65e5a1 | ||
|
|
0f19b148f6 | ||
|
|
c750be6fc6 | ||
|
|
d1003f08de | ||
|
|
386c45fd4d | ||
|
|
725d203c32 | ||
|
|
07a14ce350 | ||
|
|
77c2c8d77c | ||
|
|
9ea7f100cc | ||
|
|
51487a75e9 | ||
|
|
500b8e190d | ||
|
|
9102c12c6d | ||
|
|
cb45ee8879 | ||
|
|
ecae47236e | ||
|
|
d0ca0886bb | ||
|
|
18411f4b5f | ||
|
|
2c383e7216 | ||
|
|
cac6d3e5ac | ||
|
|
bd985d67d8 | ||
|
|
6f0a70fa66 | ||
|
|
cbe6de2a2d | ||
|
|
4885d65ec9 | ||
|
|
047896ac16 | ||
|
|
fbe3a563c3 | ||
|
|
0c453fda0b | ||
|
|
a1f74e9c63 | ||
|
|
763fa1cf0c | ||
|
|
c8e8ccfa22 | ||
|
|
597342bf15 | ||
|
|
8338b2fb49 | ||
|
|
fed0b09c4e | ||
|
|
3e76482713 | ||
|
|
d6325d902e | ||
|
|
615adc5fe6 | ||
|
|
2bdb728e87 | ||
|
|
5e82d653a1 | ||
|
|
27653b7fbf | ||
|
|
af1530953e | ||
|
|
87290af774 | ||
|
|
8469d7727d | ||
|
|
44e9ffc5ca | ||
|
|
2e86d1f9bb | ||
|
|
112c999818 | ||
|
|
858e5e9720 | ||
|
|
f2f7b10d15 | ||
|
|
4e3c2f237c | ||
|
|
c246e918f4 | ||
|
|
b76f185cb6 | ||
|
|
9d7097177d | ||
|
|
c6587596b1 | ||
|
|
b661aad9ac | ||
|
|
ca0a0a4a3d | ||
|
|
a9cd67873c | ||
|
|
b58812e7f1 | ||
|
|
9e2b4380d5 | ||
|
|
8ae8430e7c | ||
|
|
2ee25fda61 | ||
|
|
e766286d92 | ||
|
|
4df59a752a | ||
|
|
e0bf57ae36 | ||
|
|
5df66bb179 | ||
|
|
b5256ef70b | ||
|
|
6c8fec96b6 | ||
|
|
cd139bd4ec | ||
|
|
17b0c819e4 | ||
|
|
79c7d736f0 | ||
|
|
b627f93cf1 | ||
|
|
7d632ab3dd | ||
|
|
bdf80a683c | ||
|
|
ed7292abd3 | ||
|
|
e92f042677 | ||
|
|
53cf9e7422 | ||
|
|
954afd78b2 | ||
|
|
957ad2b4b1 | ||
|
|
7187c6132a | ||
|
|
b3f0d7c756 | ||
|
|
0cdfdee18f | ||
|
|
a283f56d05 | ||
|
|
e6fd78ce93 | ||
|
|
aeed5f029e | ||
|
|
04484d55de | ||
|
|
476cba228d | ||
|
|
115f9f0644 | ||
|
|
a9c2a95366 | ||
|
|
29f3891a68 | ||
|
|
7b602ef607 | ||
|
|
15e555c7f1 | ||
|
|
f4fb49d32f | ||
|
|
89be2fb736 | ||
|
|
62f0885852 | ||
|
|
355e155e69 | ||
|
|
ae1584ff3c | ||
|
|
4a7686cd33 | ||
|
|
799eeb0cb8 | ||
|
|
8452e275d0 | ||
|
|
53268000e7 | ||
|
|
52febfe3fc | ||
|
|
8fcfed495a | ||
|
|
2dfe76b082 | ||
|
|
11d8751d29 | ||
|
|
b03c3a29e0 | ||
|
|
53e8982e05 | ||
|
|
4a30841ad8 | ||
|
|
234ebadb8d | ||
|
|
11ee20fa36 | ||
|
|
440599545f | ||
|
|
44ba088cb4 | ||
|
|
08d3798722 | ||
|
|
56ff8e438e | ||
|
|
3590a3589d | ||
|
|
7674c82e1f | ||
|
|
b93b21a7f2 | ||
|
|
f53925848c | ||
|
|
eedc88b56a | ||
|
|
1102fec2a0 | ||
|
|
589fefe4b9 | ||
|
|
cfc867bd18 | ||
|
|
5bc28e3016 | ||
|
|
23b7ccca7f | ||
|
|
e9d6286a1d | ||
|
|
48321857e4 | ||
|
|
156da15715 | ||
|
|
4a0d7965cb | ||
|
|
1f522823ff | ||
|
|
6795a280fd | ||
|
|
f369e22638 | ||
|
|
a278da2eba | ||
|
|
37b2bdba79 | ||
|
|
e9519db974 | ||
|
|
dd7a24ebce | ||
|
|
bc92a7d155 | ||
|
|
a68db84df6 | ||
|
|
7b9bba3190 | ||
|
|
bcec0af232 | ||
|
|
0d437c4102 | ||
|
|
feff7bccd3 | ||
|
|
b12de3f01b | ||
|
|
0d108f12e4 | ||
|
|
4aca2ca33b | ||
|
|
9a967ae514 | ||
|
|
9481c39874 | ||
|
|
1e02065982 | ||
|
|
1fee0da689 | ||
|
|
c760cf8418 | ||
|
|
cdee5997af | ||
|
|
4289280cdc | ||
|
|
962dfa17c5 | ||
|
|
0a21aef601 | ||
|
|
8cbbd504cf | ||
|
|
91b23c8367 | ||
|
|
3729be263f | ||
|
|
ea91f4217a | ||
|
|
7fab3ce0b1 | ||
|
|
ef7d675d67 | ||
|
|
2b9d29a0fc | ||
|
|
95b95d012c | ||
|
|
4af7d5bca7 | ||
|
|
d879eb235f | ||
|
|
4f129d035b | ||
|
|
7a354c4ff4 | ||
|
|
364826b3b3 | ||
|
|
e9b308da46 | ||
|
|
94cfa2602f | ||
|
|
3533bd0504 | ||
|
|
1a51a7df9e | ||
|
|
615be89951 | ||
|
|
912ca36a1f | ||
|
|
fba93805dc | ||
|
|
96d66f4624 | ||
|
|
c3bae63e41 | ||
|
|
6c22aceabc | ||
|
|
92a77dfe7f | ||
|
|
4f2dbeda28 | ||
|
|
bec2de08fe | ||
|
|
db192e1e01 | ||
|
|
454654a9cc | ||
|
|
1018bc56eb | ||
|
|
f920dc87d0 | ||
|
|
8b97caae46 | ||
|
|
3b74aab818 | ||
|
|
e78b4939b3 | ||
|
|
621b5fc2db | ||
|
|
6ada069d5a | ||
|
|
50db384be1 | ||
|
|
ae7225ae83 | ||
|
|
911ba333a2 | ||
|
|
5cd8cce531 | ||
|
|
6a2a76cea9 | ||
|
|
7a9a3d30c9 | ||
|
|
034ca4d5eb | ||
|
|
00e3fa32fb | ||
|
|
0133bdfbe3 | ||
|
|
e563def5ba | ||
|
|
b3910f4e4d | ||
|
|
4a7b8fe839 | ||
|
|
fc56544da4 | ||
|
|
c839d25722 | ||
|
|
c6b5ecbbdb | ||
|
|
d3473afa23 | ||
|
|
379b28eb85 | ||
|
|
7f5bd33ead | ||
|
|
eef6fb9891 | ||
|
|
4a7f52ab2c | ||
|
|
10b249a162 | ||
|
|
5fc5fce663 | ||
|
|
f00fe3c0b1 | ||
|
|
3047d51613 | ||
|
|
f9f7146960 | ||
|
|
ca9dc3103a | ||
|
|
c03afa379c | ||
|
|
cbacc98e3f | ||
|
|
84daf14f1b | ||
|
|
4af28b2a46 | ||
|
|
acbc01933c | ||
|
|
7ec78eecbd | ||
|
|
87c5e37f5e | ||
|
|
d02959e3ed | ||
|
|
b844d8b750 | ||
|
|
0a3010b29f | ||
|
|
2b380d03c9 | ||
|
|
3f70253a3f | ||
|
|
165e294298 | ||
|
|
f7c9f45508 | ||
|
|
af2a924301 | ||
|
|
3981e83de5 | ||
|
|
88b9721e3f | ||
|
|
4946af1448 | ||
|
|
9959dcfa49 | ||
|
|
cfb13fad22 | ||
|
|
4e3f3a052d | ||
|
|
dc7ae9ed20 | ||
|
|
929badf4c6 | ||
|
|
c4a3f2c04f | ||
|
|
a933e458b3 | ||
|
|
06b8320815 | ||
|
|
7f3aceafd2 | ||
|
|
da5979931c | ||
|
|
d8c7e75095 | ||
|
|
187506c97f | ||
|
|
145c6d1e4f | ||
|
|
e2973f27f9 | ||
|
|
976b8180ae | ||
|
|
37acf41d43 | ||
|
|
6f26778491 | ||
|
|
834d815c87 | ||
|
|
57e58c445b | ||
|
|
8a1a8342d6 | ||
|
|
fa70ddc2c5 | ||
|
|
8ca32bb494 | ||
|
|
f6c82eba0c | ||
|
|
344044a315 | ||
|
|
b10805dc4c | ||
|
|
07f397e2ed | ||
|
|
054dc439d2 | ||
|
|
5008dcbdd4 | ||
|
|
9c6650963f | ||
|
|
d482d57689 | ||
|
|
edf6516085 | ||
|
|
957ac66e14 | ||
|
|
07ce84c4e7 | ||
|
|
918636ff03 | ||
|
|
83a6adbfa9 | ||
|
|
fcbc1d562f | ||
|
|
c3b4b58075 | ||
|
|
568b62a8a4 | ||
|
|
da34e7f507 | ||
|
|
a0c31b47e5 | ||
|
|
5fb677c0c5 | ||
|
|
168476382a | ||
|
|
7fa6a29814 | ||
|
|
f2b51da0ab | ||
|
|
53726746b8 | ||
|
|
fe0b59f559 | ||
|
|
c014dee6dc | ||
|
|
90c69d961e | ||
|
|
342f7db678 | ||
|
|
9eb704f85a | ||
|
|
7754a91929 | ||
|
|
e4dc639e54 | ||
|
|
5d90101671 | ||
|
|
437fb70852 | ||
|
|
d598404c48 | ||
|
|
32c7088600 | ||
|
|
ccede29816 | ||
|
|
b55b7e2f7b | ||
|
|
9217a6a253 | ||
|
|
07c1319b99 | ||
|
|
714b5dc26e | ||
|
|
1f715958f9 | ||
|
|
0922aca873 | ||
|
|
30ec6181b5 | ||
|
|
b28d586612 | ||
|
|
f48aacf477 | ||
|
|
bfa868a440 | ||
|
|
f01ff3a277 | ||
|
|
d88e6bf688 | ||
|
|
a3cdacd088 | ||
|
|
81d99c855f | ||
|
|
5cd110f625 | ||
|
|
416895ff30 | ||
|
|
e41abb6e92 | ||
|
|
a6440a3fa6 | ||
|
|
2dece7ecaf | ||
|
|
7aae525587 | ||
|
|
ac5314093b | ||
|
|
1524fb9fa9 | ||
|
|
957549460b | ||
|
|
3b33f54fb8 | ||
|
|
42ab6b6b66 | ||
|
|
f59a5bbabc | ||
|
|
0be371d747 | ||
|
|
2b52210291 | ||
|
|
96a7bce78e | ||
|
|
c1e1ea697c | ||
|
|
874d6ebf2c | ||
|
|
77f5eb703c | ||
|
|
af53ae8329 | ||
|
|
8f76b8880e | ||
|
|
fa398734be | ||
|
|
362d20a8c7 | ||
|
|
6a33b8aeeb | ||
|
|
d4e06ac436 | ||
|
|
817dcd37e0 | ||
|
|
25bfd3c50f | ||
|
|
b13c902fb0 | ||
|
|
c95ef44b02 | ||
|
|
162727590c | ||
|
|
7e159844fb | ||
|
|
787b79cc2c | ||
|
|
b77652b499 | ||
|
|
0c8444b8ed | ||
|
|
3e6ee799ba | ||
|
|
dd14ccb115 | ||
|
|
ba0fcd27c3 | ||
|
|
d476e67067 | ||
|
|
4588f5e9ab | ||
|
|
68f54d364b | ||
|
|
7dba18e7b9 | ||
|
|
67b265fe96 | ||
|
|
8289269a86 | ||
|
|
9f711ed821 | ||
|
|
73e2ab5125 | ||
|
|
7ea2ab1672 | ||
|
|
c821e903f8 | ||
|
|
54db04521a | ||
|
|
91fdecd76f | ||
|
|
f140a74a13 | ||
|
|
4854a2a81b | ||
|
|
d94bb65006 | ||
|
|
6ca5280b2c | ||
|
|
5da3e1deea | ||
|
|
1ae85d0e39 | ||
|
|
256e3a467c | ||
|
|
4477fe4dd6 | ||
|
|
5d1e245858 | ||
|
|
ec750a44c9 | ||
|
|
006f1d9802 | ||
|
|
638b3d4ee1 | ||
|
|
a1cc1651fa | ||
|
|
9fe141f5ad | ||
|
|
d52f0c7d40 | ||
|
|
bb55c4a855 | ||
|
|
f1a06b14de | ||
|
|
286f3dc093 | ||
|
|
a731322782 | ||
|
|
0db07ec25e | ||
|
|
bc112ba65f | ||
|
|
62ba322658 | ||
|
|
02135b550d | ||
|
|
ee4b06bb50 | ||
|
|
16c5435ca8 | ||
|
|
2595049748 | ||
|
|
5911691c0d | ||
|
|
e369bddc84 | ||
|
|
dccf2bbb4a | ||
|
|
eaab3fc038 | ||
|
|
858e1aba67 | ||
|
|
19eff7791d | ||
|
|
c81af4ffe0 | ||
|
|
9675e4233b | ||
|
|
e6a176bb1e | ||
|
|
ff0980914b | ||
|
|
43e5ccd0a7 | ||
|
|
66d6272942 | ||
|
|
2f1b828967 | ||
|
|
622636dcf1 | ||
|
|
0c22c276bf | ||
|
|
7a4a79c74e | ||
|
|
06f454e1d3 | ||
|
|
c1dbd52de1 | ||
|
|
c3f5679188 | ||
|
|
97e2628f95 | ||
|
|
6cecfcb704 | ||
|
|
022a5a16f5 | ||
|
|
a39a834e75 | ||
|
|
2a1210384a | ||
|
|
d497611069 | ||
|
|
46d8786f5a | ||
|
|
b8028729eb | ||
|
|
30e7768a87 | ||
|
|
10dc663e07 | ||
|
|
42fc57d761 | ||
|
|
74cd2f4844 | ||
|
|
a15135f1c1 | ||
|
|
ccd84c0be6 | ||
|
|
510215f284 | ||
|
|
c7ea0aacd6 | ||
|
|
f7f089d2d4 | ||
|
|
82721c77a1 | ||
|
|
1c9bf7d91c | ||
|
|
9bf78396cb | ||
|
|
d994e4719c | ||
|
|
44b886bb76 | ||
|
|
8d2f012bcf | ||
|
|
a86deed5f6 | ||
|
|
3fd9ad7a60 | ||
|
|
319a5cf97c | ||
|
|
0fd503d6af | ||
|
|
bf696026bd | ||
|
|
734657244b | ||
|
|
d2470e4f9c | ||
|
|
28a2792280 | ||
|
|
cd985a33d8 | ||
|
|
726d2beffd | ||
|
|
f04be3fc1b | ||
|
|
b6927410d9 | ||
|
|
44b2e1ef8b | ||
|
|
3d01e6af89 | ||
|
|
00387b2076 | ||
|
|
f9bf514801 | ||
|
|
fa27bddfab | ||
|
|
f27e8f8ddc | ||
|
|
5b2623ff2e | ||
|
|
a83a726b6e | ||
|
|
93df7e00a7 | ||
|
|
6b7748a88d | ||
|
|
f102c77fa2 | ||
|
|
a4fa261b77 | ||
|
|
8a15fefc6c | ||
|
|
12a4cc16be | ||
|
|
6335716342 | ||
|
|
db0602ac2a | ||
|
|
390ad530f1 | ||
|
|
6eb2e8d68a | ||
|
|
b804b3b221 | ||
|
|
936c1118bd | ||
|
|
4ba7b8a8ff | ||
|
|
70601e9da0 | ||
|
|
c32d1f9614 | ||
|
|
e031f78ad4 | ||
|
|
7d0273051a | ||
|
|
29d537571b | ||
|
|
39f243f76b | ||
|
|
0712360cc9 | ||
|
|
02c125cbb4 | ||
|
|
13256fb7e9 | ||
|
|
f11d757807 | ||
|
|
2e123849fb | ||
|
|
2f6cfaf0e9 | ||
|
|
f9b216d6f9 | ||
|
|
5fdd10d77e | ||
|
|
41de02d528 | ||
|
|
1c3d08f23a | ||
|
|
0f1dc1fd50 | ||
|
|
cd06018820 | ||
|
|
7816eb6344 | ||
|
|
9813f4b55f | ||
|
|
f81ca21b22 | ||
|
|
f1b7620c9e | ||
|
|
7d5c453f59 | ||
|
|
bc4feb42b5 | ||
|
|
ca9920874f | ||
|
|
415991f6fc | ||
|
|
20c52def19 | ||
|
|
7dcacbcfc4 | ||
|
|
34bf1560a9 | ||
|
|
39195ac97a | ||
|
|
6aa71e1f72 | ||
|
|
257a6c45f8 | ||
|
|
d34a11b584 | ||
|
|
ca64c96133 | ||
|
|
ff734e3269 | ||
|
|
d028a60cc2 | ||
|
|
577f58149c | ||
|
|
4b97e191b8 | ||
|
|
15a148ab10 | ||
|
|
5ac7741ca9 | ||
|
|
4c7cff6e8e | ||
|
|
c6ca85b525 | ||
|
|
99f45b474e | ||
|
|
ee44c90e85 | ||
|
|
2c4fa48f46 | ||
|
|
90fcd9369d | ||
|
|
923feda9f7 | ||
|
|
6d7d2ea5fe | ||
|
|
4874a1801b | ||
|
|
479d8fc0f6 | ||
|
|
1c346b2531 | ||
|
|
5cdebaf896 | ||
|
|
600602f9dc | ||
|
|
2a530bb9d2 | ||
|
|
acdad5caf3 | ||
|
|
b42b243287 | ||
|
|
a76f5f3db7 | ||
|
|
4e9f745d4a | ||
|
|
101961a7c6 | ||
|
|
29d1f860c1 | ||
|
|
2663e73f1c | ||
|
|
1f9d0bb196 | ||
|
|
ff9f262fac | ||
|
|
472dc3bd41 | ||
|
|
6f91b93519 | ||
|
|
47291f68b2 | ||
|
|
2b5ef3c572 | ||
|
|
9c50496d93 | ||
|
|
80488e2f23 | ||
|
|
ad8da7166b | ||
|
|
55cb918c51 | ||
|
|
ac55c5ccf7 | ||
|
|
5bcf90766f | ||
|
|
8f12fdea4a | ||
|
|
6f687ee402 | ||
|
|
9dfe98abb0 | ||
|
|
399cf70b92 | ||
|
|
571790097a | ||
|
|
21f3c7c8c2 | ||
|
|
9d26167ec1 | ||
|
|
ba4906d05c | ||
|
|
e13a11eb7f | ||
|
|
72b214b8db | ||
|
|
84a8fb71b8 | ||
|
|
4f5272cab9 | ||
|
|
5895047e23 | ||
|
|
50bcf8db34 | ||
|
|
7defd3bbed | ||
|
|
b9ecc931b0 | ||
|
|
b84a8fd737 | ||
|
|
2b1a2ce09c | ||
|
|
bcf36610e1 | ||
|
|
1bb3254d4d | ||
|
|
0f95d507c4 | ||
|
|
aa58e21bda | ||
|
|
eac0412d18 | ||
|
|
0c8aa84f2f | ||
|
|
3d874d1618 | ||
|
|
b8edd99dbd | ||
|
|
0df5ebf0fa | ||
|
|
809535b934 | ||
|
|
854e957b78 | ||
|
|
df24f29232 | ||
|
|
14c7d9ab14 | ||
|
|
0e36ac6b72 | ||
|
|
0d2cdbbdfe | ||
|
|
48f9bee21e | ||
|
|
dd8fc049ff | ||
|
|
abd22f1273 | ||
|
|
4a5817d8ba | ||
|
|
eab084c9a2 | ||
|
|
80ea2383a7 | ||
|
|
ec76fbe027 | ||
|
|
c772038e77 | ||
|
|
59b1a8e71c | ||
|
|
83c38876fe | ||
|
|
9163c40a1a | ||
|
|
8b79380977 | ||
|
|
34c9d895c8 | ||
|
|
bf8bb83ec5 | ||
|
|
328697952f | ||
|
|
3c19b89d9a | ||
|
|
ae9f394906 | ||
|
|
8467f36b80 | ||
|
|
43a9571b2c | ||
|
|
bbef71dc7d | ||
|
|
c4df3c6562 | ||
|
|
0ad3bfd0ab | ||
|
|
fb7c450b76 | ||
|
|
3fc70519cf | ||
|
|
98c2bf8ff2 | ||
|
|
f9c8bf15bb | ||
|
|
a7e19ffb0b | ||
|
|
7609a1c7c6 | ||
|
|
087e2d6e35 | ||
|
|
bb7710a5a2 | ||
|
|
0d582e0e79 | ||
|
|
3d0579cc08 | ||
|
|
352e390c7b | ||
|
|
394037a127 | ||
|
|
9d4e235cf6 | ||
|
|
cfbc1a6b48 | ||
|
|
31b8b58de9 | ||
|
|
a77a835694 | ||
|
|
dca5c5108b | ||
|
|
e14e4e156c | ||
|
|
05ce65d9d2 | ||
|
|
b952e45036 | ||
|
|
4c630512fe | ||
|
|
0461d25de6 | ||
|
|
2df120af72 | ||
|
|
791b7e1a1b | ||
|
|
f6f4e59473 | ||
|
|
60924e82e2 | ||
|
|
75bd427b8e | ||
|
|
715118ce39 | ||
|
|
e3deb8275d | ||
|
|
c30e12f956 | ||
|
|
983b23db92 | ||
|
|
ed2da9bedb | ||
|
|
409ff3c179 | ||
|
|
39eab72293 | ||
|
|
71ea2bec86 | ||
|
|
c9af6ca94b | ||
|
|
72d5bac69f | ||
|
|
6e0733afa2 | ||
|
|
e660cc50c6 | ||
|
|
e6b40f54cd | ||
|
|
c2af21169d | ||
|
|
4f7af97f8c | ||
|
|
57f54952c3 | ||
|
|
b321b6d9db | ||
|
|
56c5227cf7 | ||
|
|
ae2931ba1b | ||
|
|
9e3589ec4d | ||
|
|
61b7094dbd | ||
|
|
50ecc751d1 | ||
|
|
bb536a0eaa | ||
|
|
8b7527318d | ||
|
|
f2ac0145da | ||
|
|
06fe0f1bcc | ||
|
|
7ea2447246 | ||
|
|
0adf4477a3 | ||
|
|
b3311fd59d | ||
|
|
ae109f13a2 | ||
|
|
cb1901e111 | ||
|
|
bbc052bedc | ||
|
|
f2797ec262 | ||
|
|
a21727741f | ||
|
|
5f022269b1 | ||
|
|
0e76fcf706 | ||
|
|
6b4dc2901d | ||
|
|
bcf864fce3 | ||
|
|
0168d8fbc8 | ||
|
|
88b1c1b926 | ||
|
|
1f93827b63 | ||
|
|
8e3ba0bba3 | ||
|
|
42a0441cb8 | ||
|
|
7b091b86d2 | ||
|
|
f346eaf693 | ||
|
|
038be89766 | ||
|
|
a682dd9362 | ||
|
|
387e8aadc6 | ||
|
|
da273519fd | ||
|
|
8c2d6bb31b | ||
|
|
3cb4a029e0 | ||
|
|
037f952136 | ||
|
|
7fc441801d | ||
|
|
c389e057b4 | ||
|
|
2c7829f50e | ||
|
|
0593074196 | ||
|
|
c7626150fc | ||
|
|
f6990fedc7 | ||
|
|
adb02376eb | ||
|
|
65b6eb0c27 | ||
|
|
654354e681 | ||
|
|
f1a709e074 | ||
|
|
87b011e7e8 | ||
|
|
6bb7c2d7b3 | ||
|
|
7d9770762c | ||
|
|
df8c8f025c | ||
|
|
51264c30cc | ||
|
|
1d5fb97981 | ||
|
|
a06540e471 | ||
|
|
f79dc1c2e7 | ||
|
|
8a94c597a0 | ||
|
|
8a9a3a00bd | ||
|
|
8c8b4ee332 | ||
|
|
a295ac6590 | ||
|
|
e49e0d2705 | ||
|
|
4fd20185e9 | ||
|
|
920125794a | ||
|
|
ca6c28ed93 | ||
|
|
e9757c46e3 | ||
|
|
7e840acd19 | ||
|
|
6f76db9c6c | ||
|
|
86489dd5a7 | ||
|
|
33f139e516 | ||
|
|
30d9331079 | ||
|
|
8207dc756a | ||
|
|
1887594d8a | ||
|
|
ee17b41e62 | ||
|
|
5e8d775b87 | ||
|
|
f4d457998f | ||
|
|
bd0175c167 | ||
|
|
81ffe96c76 | ||
|
|
e5fbe651d8 | ||
|
|
a91112e5d9 | ||
|
|
2b5f421501 | ||
|
|
ecd7905e8f | ||
|
|
8f989f318b | ||
|
|
7b9dad44d1 | ||
|
|
f5eab48017 | ||
|
|
66ff762fbb | ||
|
|
2bdd01d084 | ||
|
|
2bdc4cdffa | ||
|
|
90a6d484b7 | ||
|
|
021aa51707 | ||
|
|
48fffd7a7b | ||
|
|
17033037eb | ||
|
|
f43b913302 | ||
|
|
f7b087ed8f | ||
|
|
8cecbe31a7 | ||
|
|
f2055b0d80 | ||
|
|
28e5bedf49 | ||
|
|
f8a9b922be | ||
|
|
2a199af8f7 | ||
|
|
2373020225 | ||
|
|
e13d09242c | ||
|
|
09eba4c38f | ||
|
|
2aa23a317d | ||
|
|
5cd513859d | ||
|
|
c6cba55667 | ||
|
|
65ce6ddf1d | ||
|
|
fa7b1404c1 | ||
|
|
61b528c85d | ||
|
|
77b1b247c4 | ||
|
|
a06430c5fa | ||
|
|
0e38aa7f37 | ||
|
|
707ce53c16 | ||
|
|
19982e5551 | ||
|
|
170bbea166 | ||
|
|
6b5ea675c3 | ||
|
|
d873aec9e6 | ||
|
|
0d1efb61e2 | ||
|
|
a27c2f7a80 | ||
|
|
36d85eb02e | ||
|
|
9ae0940e99 | ||
|
|
2f4e12916d | ||
|
|
c860d74cba | ||
|
|
8cd3e16e26 | ||
|
|
94063f7862 | ||
|
|
a0ff708d29 | ||
|
|
6bfbeb3dfa | ||
|
|
3158d28264 | ||
|
|
997e84f117 | ||
|
|
bc91db64d7 | ||
|
|
82ef6ec659 | ||
|
|
374b55be8a | ||
|
|
72e1c1a7f6 | ||
|
|
173021377e | ||
|
|
17879958ca | ||
|
|
31a8be0434 | ||
|
|
87d619e02a | ||
|
|
f4aa72373b | ||
|
|
3cb9ecae78 | ||
|
|
88caf4f5b6 | ||
|
|
a75ee50533 | ||
|
|
8e941417a5 | ||
|
|
e8d2bbd2c9 | ||
|
|
065a53b997 | ||
|
|
ca5a222aec | ||
|
|
4320c73336 | ||
|
|
7f98265272 | ||
|
|
0b75a8e94e | ||
|
|
eb3e237e47 | ||
|
|
b1796c0acb | ||
|
|
bff10e5711 | ||
|
|
0f559f3f97 | ||
|
|
34aead4d49 | ||
|
|
7cc01e155c | ||
|
|
7fe5fb92b4 | ||
|
|
b084f8a616 | ||
|
|
802a2f3fdb | ||
|
|
06f6f2ff21 | ||
|
|
b37198106d | ||
|
|
604928adc4 | ||
|
|
4a6762540d | ||
|
|
af5176be70 | ||
|
|
482006ed1a | ||
|
|
5923e20b7e | ||
|
|
14cca4610b | ||
|
|
2dbb0093c1 | ||
|
|
d91b6e9a1b | ||
|
|
ada55bd9e2 | ||
|
|
5113de875e | ||
|
|
e079006a4b | ||
|
|
07561794e9 | ||
|
|
75a0da31fb | ||
|
|
33ee2a43c5 | ||
|
|
dcb6a88c63 | ||
|
|
eeda822196 | ||
|
|
060f59daa8 | ||
|
|
4117614861 | ||
|
|
e76440e940 | ||
|
|
f8490a8850 | ||
|
|
ee1cc99c65 | ||
|
|
dcf7e7cf0c | ||
|
|
4c8bcd918b | ||
|
|
a26bb0390d | ||
|
|
26a0df8253 | ||
|
|
526d99f832 | ||
|
|
acbb5be6ab | ||
|
|
522a29241b | ||
|
|
b8d3c84d3c | ||
|
|
9d520877d1 | ||
|
|
5cda0581cd | ||
|
|
ce2e9de6fb | ||
|
|
4d53fb97b6 | ||
|
|
d274a8395b | ||
|
|
ba86f516d8 | ||
|
|
ac02c763c7 | ||
|
|
7407a6b144 | ||
|
|
0453e05bb2 | ||
|
|
946a93164a | ||
|
|
fe02cae4f7 | ||
|
|
5762eb9b33 | ||
|
|
73ffc4a13f | ||
|
|
865ef2ab7f | ||
|
|
7d35ed4eda | ||
|
|
ec3cc6abe8 | ||
|
|
6f7957fd40 | ||
|
|
ec4de3326e | ||
|
|
f030618d19 | ||
|
|
5bcb9010f6 | ||
|
|
780fff70c4 | ||
|
|
1d94d7e604 | ||
|
|
a6cac2886b | ||
|
|
2566b8732e | ||
|
|
d4c50383af | ||
|
|
1ee7bd2a60 | ||
|
|
0bbfa9b483 | ||
|
|
2cad1b3d93 | ||
|
|
bcaa1043ea | ||
|
|
0b33d1800d | ||
|
|
946942214f | ||
|
|
cd6476e487 | ||
|
|
0b02fd4e99 | ||
|
|
d779a94cfb | ||
|
|
2f89a8eb58 | ||
|
|
26d3375900 | ||
|
|
b06e8c3022 | ||
|
|
8a20f8b2da | ||
|
|
e1099e9370 | ||
|
|
68c8901c2a | ||
|
|
cfb1aebf66 | ||
|
|
e4f54bd53a | ||
|
|
30ea4dd46e | ||
|
|
d5c33a203d | ||
|
|
087c09cc65 | ||
|
|
a9bb2a017e | ||
|
|
8a049b8ee7 | ||
|
|
37efd93725 | ||
|
|
3e61803e89 | ||
|
|
3173d88f3f | ||
|
|
f96a898c51 | ||
|
|
d66b79f468 | ||
|
|
b7e300d155 | ||
|
|
4bd680cec8 | ||
|
|
78ae892db6 | ||
|
|
d748e371e5 | ||
|
|
6bdc89252e | ||
|
|
c104f0167f | ||
|
|
6e3c6d1ba8 | ||
|
|
b77262ba13 | ||
|
|
960ebb13db | ||
|
|
1a7b331a4b | ||
|
|
3092e07281 | ||
|
|
a5d53d1ac8 | ||
|
|
3c5df28101 | ||
|
|
49e071d363 | ||
|
|
6e06ff048d | ||
|
|
c5ee39f54b | ||
|
|
f7b1e4ec09 | ||
|
|
e6830b2c19 | ||
|
|
fe3cf386c3 | ||
|
|
0a6a213891 | ||
|
|
2103e691db | ||
|
|
cf15a99730 | ||
|
|
a3102b552c | ||
|
|
bd0257cbe5 | ||
|
|
56e7b2a592 | ||
|
|
61d030748c | ||
|
|
f59ed991fe | ||
|
|
2bdf958663 | ||
|
|
bd8b6a2a64 | ||
|
|
88528e338b | ||
|
|
88b3bf1887 | ||
|
|
6907df1457 | ||
|
|
19036c14f5 | ||
|
|
ddb1236f2f | ||
|
|
30ef9c6418 | ||
|
|
8763fd1c53 | ||
|
|
5976005c4a | ||
|
|
63eed8994a | ||
|
|
f458dbdbcb | ||
|
|
b7421fd5cd | ||
|
|
a2feb04509 | ||
|
|
e25fee71a2 | ||
|
|
bfe2a6656c | ||
|
|
e15ca5c642 | ||
|
|
3232c5be86 | ||
|
|
1c5a50d4cb | ||
|
|
4ef5f77161 | ||
|
|
d27e5a5e1d | ||
|
|
7ecf76490c | ||
|
|
12120413f9 | ||
|
|
c0eea6e667 | ||
|
|
5c54aecdda | ||
|
|
5cfc0cce14 | ||
|
|
d9a58ef830 | ||
|
|
dfd85da9d7 | ||
|
|
94edc13393 | ||
|
|
a9baa519f3 | ||
|
|
a6c859c9cc | ||
|
|
f9a67b34b2 | ||
|
|
6ac5735d14 | ||
|
|
9d5e8b9ad8 | ||
|
|
bd72ee9cd1 | ||
|
|
c2e115b6a5 | ||
|
|
61ba4cd1ce | ||
|
|
244e0fa5e6 | ||
|
|
134bc44c45 | ||
|
|
1d2dc98f50 | ||
|
|
7a05b89a93 | ||
|
|
2bfeb20550 | ||
|
|
fa779034b5 | ||
|
|
ea5cfdcdce | ||
|
|
ba1eab1bf0 | ||
|
|
149c60bd2e | ||
|
|
9795a27482 | ||
|
|
baccdba75c | ||
|
|
93b4c6291a | ||
|
|
815edf1ba5 | ||
|
|
df7b4d81c7 | ||
|
|
3e07ba1012 | ||
|
|
32c6906750 | ||
|
|
3ebe4c47ba | ||
|
|
5b803f00e1 | ||
|
|
9a0118d991 | ||
|
|
093aae1f46 | ||
|
|
e431318dc0 | ||
|
|
c15812add2 | ||
|
|
3375cdbb49 | ||
|
|
559b564714 | ||
|
|
3ac4cfb9a7 | ||
|
|
a4d651ce9a | ||
|
|
d3bbc0eaa5 | ||
|
|
9ff90c98cd | ||
|
|
b8aaf7d7b1 | ||
|
|
c0ecde90bc | ||
|
|
83719a6f48 | ||
|
|
28011bbf55 | ||
|
|
88170f6dc4 | ||
|
|
931aab22bb | ||
|
|
6cb4fbb1c4 | ||
|
|
54a551e488 | ||
|
|
5a0d84f185 | ||
|
|
222396759b | ||
|
|
128c0ed5a1 | ||
|
|
ea74e34446 | ||
|
|
c7225a059f | ||
|
|
c1f8ae662f | ||
|
|
7d3227128c | ||
|
|
182b6755f5 | ||
|
|
0945f79ced | ||
|
|
8b611322e5 | ||
|
|
b255796b33 | ||
|
|
2ae7c60780 | ||
|
|
279ad90a3c | ||
|
|
bed7a7d29c | ||
|
|
f02a3c5b47 | ||
|
|
d7df5126ce | ||
|
|
97ecfe7e03 | ||
|
|
f30fde3a52 | ||
|
|
d7273dee1c | ||
|
|
55dff4d512 | ||
|
|
693b21188c | ||
|
|
220734ccac | ||
|
|
bf84024d6b | ||
|
|
7bb39ae541 | ||
|
|
d250057a7c | ||
|
|
d07454659a | ||
|
|
913d2984ce | ||
|
|
e2d75c0b76 | ||
|
|
8aba486295 | ||
|
|
66f2cd81a8 | ||
|
|
87bda9e124 | ||
|
|
954d019895 | ||
|
|
41132af773 | ||
|
|
9a5b89da59 | ||
|
|
c12ffa21da | ||
|
|
0b5937a396 | ||
|
|
773bb0651e | ||
|
|
8817b1e2af | ||
|
|
366ee6d24b | ||
|
|
0d58869d6e | ||
|
|
52ba3c7f80 | ||
|
|
14d2bae238 | ||
|
|
e331512473 | ||
|
|
1de6a21f3a | ||
|
|
43d8c81104 | ||
|
|
89930f34d7 | ||
|
|
59ea6b120c | ||
|
|
7c312d358b | ||
|
|
ac2746f680 | ||
|
|
e2b4178f42 | ||
|
|
266954be99 | ||
|
|
2e3ae9decb | ||
|
|
6741698f71 | ||
|
|
ccae1cc430 | ||
|
|
241a5bf4e5 | ||
|
|
e36aba8c66 | ||
|
|
1a0baef147 | ||
|
|
9a49d267eb | ||
|
|
7a832f1fdb | ||
|
|
16c391c78c | ||
|
|
92aae63af2 | ||
|
|
b042644c85 | ||
|
|
97afc4bd0c | ||
|
|
a67b29a576 | ||
|
|
97c87d0a99 | ||
|
|
fedf8d9935 | ||
|
|
23bfb84e38 | ||
|
|
c7d16fbf9e | ||
|
|
033a3dd620 | ||
|
|
f5a0b2fed8 | ||
|
|
b03dcfb7de | ||
|
|
502094439c | ||
|
|
c15f812366 | ||
|
|
dd1b102282 | ||
|
|
67b3cdc7b7 | ||
|
|
051994bdf4 | ||
|
|
0f7c12b517 | ||
|
|
aa2b0090d3 | ||
|
|
00b27c20da | ||
|
|
7ecd7e84d9 | ||
|
|
49c2dbd4a7 | ||
|
|
cf46535b66 | ||
|
|
91e2e6f207 | ||
|
|
b63434ce2e | ||
|
|
dde6c42421 | ||
|
|
beb6cca88d | ||
|
|
ba2f18ce21 | ||
|
|
c928eded74 | ||
|
|
9baefc2e56 | ||
|
|
313fe2c76c | ||
|
|
53c69e7ad5 | ||
|
|
3ff935d4c4 | ||
|
|
9fa89e8596 | ||
|
|
6c20af07f7 | ||
|
|
56abd7ba70 | ||
|
|
dc1769b28a | ||
|
|
97b863101b | ||
|
|
0a1b62a760 | ||
|
|
f2fa852f1a | ||
|
|
59f4ddf5af | ||
|
|
673d857bd8 | ||
|
|
36be16b3e9 | ||
|
|
390bb1988d | ||
|
|
63deae3ab2 | ||
|
|
710374ed1e | ||
|
|
8f1dc2522a | ||
|
|
9c3dd76e25 | ||
|
|
3328087de1 | ||
|
|
ec3f5ff40b | ||
|
|
3b000f080e | ||
|
|
09046c53ef | ||
|
|
13331d3eab | ||
|
|
a2a1a557f5 | ||
|
|
fff4cc8b0d | ||
|
|
aa0fc6dfe7 | ||
|
|
c639ac0c5a | ||
|
|
45aa77079d | ||
|
|
8e57090a75 | ||
|
|
e7cb8c8b4f | ||
|
|
57002aca36 | ||
|
|
5956d3ec77 | ||
|
|
2d522de701 | ||
|
|
aef987d832 | ||
|
|
c5d90745a0 | ||
|
|
1d160762b5 | ||
|
|
b45b9e5ccf | ||
|
|
4b9931c417 | ||
|
|
34424d7a00 | ||
|
|
7cd32fc4eb | ||
|
|
c9097566e2 | ||
|
|
e26556c631 | ||
|
|
bd32dce19a | ||
|
|
152a3f2e5f | ||
|
|
4fe6815062 | ||
|
|
525979afaa | ||
|
|
93a10f33d5 | ||
|
|
c9b4fb418a | ||
|
|
2151bf8f9a | ||
|
|
fa64ef6f00 | ||
|
|
a31c0e9082 | ||
|
|
365ce29761 | ||
|
|
93ca98d3a8 | ||
|
|
6e86a498ad | ||
|
|
94cfe30b77 | ||
|
|
cca3acc035 | ||
|
|
f0e3fd9e72 | ||
|
|
8388163aaf | ||
|
|
a203214ef9 | ||
|
|
4250893d2f | ||
|
|
0c1e2a7347 | ||
|
|
d5c35a1d83 | ||
|
|
722036f10e | ||
|
|
8eab74ea81 | ||
|
|
473d38c846 | ||
|
|
a9fb1b25a8 | ||
|
|
360dbd9e5e | ||
|
|
8c4f9d913d | ||
|
|
e4b1377b0e | ||
|
|
fc5e0fb012 | ||
|
|
9a140643c8 | ||
|
|
5fbba7bc01 | ||
|
|
4cf7ab3425 | ||
|
|
b7f93bd4ea | ||
|
|
962a08700e | ||
|
|
d23daf225d | ||
|
|
e5f2b0c0a9 | ||
|
|
6aa80b07e7 | ||
|
|
be0ae2389c | ||
|
|
7d8b6d149e | ||
|
|
a47fbc18f7 | ||
|
|
47ad802ab6 | ||
|
|
8a3e786294 | ||
|
|
4018b284e3 | ||
|
|
b704d42fe4 | ||
|
|
5dab2802b3 | ||
|
|
377fbed517 | ||
|
|
eab0a73f53 | ||
|
|
558170582a | ||
|
|
10ffaec730 | ||
|
|
f17876969d | ||
|
|
81777a29d5 | ||
|
|
3944786c13 | ||
|
|
af939fad66 | ||
|
|
79f8f3eb14 | ||
|
|
9137b38fb9 | ||
|
|
4bb5ee4b17 | ||
|
|
022c8502c0 | ||
|
|
b601ba55d0 | ||
|
|
8de3571aa8 | ||
|
|
5a6bc4404a | ||
|
|
17eb4a2660 | ||
|
|
81124780d0 | ||
|
|
aed7e14d4b | ||
|
|
6835c344eb | ||
|
|
0b965d1ee4 | ||
|
|
ed184acb40 | ||
|
|
7d7eac5030 | ||
|
|
68dbb13084 | ||
|
|
27d335ebe1 | ||
|
|
900e035412 | ||
|
|
bc552d326c | ||
|
|
7ffc983edd | ||
|
|
4a81d366bb | ||
|
|
383a51dde8 | ||
|
|
2a6060e425 | ||
|
|
576269dae9 | ||
|
|
ac34e0e108 | ||
|
|
11bd4c3223 | ||
|
|
8d88a92fe4 | ||
|
|
6004a35e23 | ||
|
|
a3a633242f | ||
|
|
4ad579d4ad | ||
|
|
2666c7312f | ||
|
|
516f30a307 | ||
|
|
9d3d50c654 | ||
|
|
453fbbed1b | ||
|
|
0ce8ab7bce | ||
|
|
d72128107e | ||
|
|
3b8dc924c3 | ||
|
|
08ac287726 | ||
|
|
a8d6f40794 | ||
|
|
a2071feeb1 | ||
|
|
aa705b07f3 | ||
|
|
fbbc1981ca | ||
|
|
6528bd0e4f | ||
|
|
81a07899ae | ||
|
|
c18d8fa967 | ||
|
|
3caa91cc36 | ||
|
|
0bdf3542e4 | ||
|
|
23769371bc | ||
|
|
bccd854676 | ||
|
|
2fa0910547 | ||
|
|
c170b1b83e | ||
|
|
be6016a972 | ||
|
|
a56f66e721 | ||
|
|
e589d7f1e1 | ||
|
|
948cde1a31 | ||
|
|
3447aaa8c6 | ||
|
|
688c64ce21 | ||
|
|
7eb42dc36b | ||
|
|
ae1c1b3a47 | ||
|
|
74078552df | ||
|
|
5da8206915 | ||
|
|
f271726cd8 | ||
|
|
22f6612354 | ||
|
|
74fe5bc4dd | ||
|
|
69d7011baf | ||
|
|
0301d4462b | ||
|
|
7c009e2443 | ||
|
|
a16d9f91ee | ||
|
|
7e76c85535 | ||
|
|
3054694726 | ||
|
|
a25021d215 | ||
|
|
532833ff70 | ||
|
|
e79a66851c | ||
|
|
97825fb2c7 | ||
|
|
bd9df7e619 | ||
|
|
087f09e9a6 | ||
|
|
1257b32464 | ||
|
|
a437af44f8 | ||
|
|
9644610e04 | ||
|
|
71cbe1cf50 | ||
|
|
edad2a1ee5 | ||
|
|
0e597f5768 | ||
|
|
b28dc55237 | ||
|
|
a2dec7a05d | ||
|
|
db9fb22cf4 | ||
|
|
412a00249f | ||
|
|
ccb7a8f94f | ||
|
|
ee26e13bea | ||
|
|
493ff9c685 | ||
|
|
bbc49e1ba3 | ||
|
|
0ef39e4440 | ||
|
|
8a956bcdf6 | ||
|
|
a16ff29638 | ||
|
|
f6381e7e5e | ||
|
|
e014765797 | ||
|
|
3899684686 | ||
|
|
e11b457b79 | ||
|
|
a04cbd111c | ||
|
|
6c7d3e1eab | ||
|
|
d965b41bdd | ||
|
|
d660c12a74 | ||
|
|
43bcbf771e | ||
|
|
7f420361b1 | ||
|
|
361455678a | ||
|
|
47c1c6288c | ||
|
|
07abc9fac4 | ||
|
|
266923d9e8 | ||
|
|
622ff9d764 | ||
|
|
b75d11da3a | ||
|
|
8af49161fb | ||
|
|
ca872af3c8 | ||
|
|
aeccf45d4e | ||
|
|
dcae0eadd5 | ||
|
|
80effaa541 | ||
|
|
edd93c80a1 | ||
|
|
39646acf5b | ||
|
|
f697d2daa1 | ||
|
|
607631604f | ||
|
|
09d012a10b | ||
|
|
b303d49634 | ||
|
|
371723a5d4 | ||
|
|
4481c3bada | ||
|
|
70bb30b95a | ||
|
|
ebc641440e | ||
|
|
586b4db968 | ||
|
|
12c7981450 | ||
|
|
08c909fd41 | ||
|
|
44e43d3b47 | ||
|
|
9e8273c7f7 | ||
|
|
93735c7bf1 | ||
|
|
e37a97e2d5 | ||
|
|
8ff5450ece | ||
|
|
5d30ddac22 | ||
|
|
80f697ef2a | ||
|
|
47c7748707 | ||
|
|
9f33aa2afc | ||
|
|
1dc6600b59 | ||
|
|
1ec58c1161 | ||
|
|
d023d577b2 | ||
|
|
21d65ca0bf | ||
|
|
bcf4401858 | ||
|
|
262396d48b | ||
|
|
0a9d5f680f | ||
|
|
64239f1c04 | ||
|
|
7590d546f1 | ||
|
|
021070f066 | ||
|
|
55a4318839 | ||
|
|
90647f30f8 | ||
|
|
8cc9080d36 | ||
|
|
6e5fc91885 | ||
|
|
71de2b5ec5 | ||
|
|
7703f91ee2 | ||
|
|
ecc8abcc50 | ||
|
|
14917c9791 | ||
|
|
25c56164b0 | ||
|
|
12988b879e | ||
|
|
684e391a9a | ||
|
|
7a16cd4c37 | ||
|
|
b3117c2b02 | ||
|
|
6a75fa83b5 | ||
|
|
88a8721b89 | ||
|
|
1f12857551 | ||
|
|
71032f6c4c | ||
|
|
088b1cab83 | ||
|
|
f40a534bfb | ||
|
|
f278530239 | ||
|
|
0389aab0a3 | ||
|
|
51a66a3202 | ||
|
|
248985e51a | ||
|
|
996d83eae0 | ||
|
|
98a1329dd7 | ||
|
|
ed2ebc7d3d | ||
|
|
41634f9998 | ||
|
|
93501af046 | ||
|
|
078585db28 | ||
|
|
03e9e4c1d9 | ||
|
|
4a1d077238 | ||
|
|
f7a5e6deb8 | ||
|
|
dabb22bb6a | ||
|
|
3d03ca3d10 | ||
|
|
386992c3b8 | ||
|
|
a48f252cfa | ||
|
|
c3a311ab85 | ||
|
|
7926e1bc3c | ||
|
|
b796db648a | ||
|
|
0964ecac8c | ||
|
|
dd1ac7952b | ||
|
|
7d1cbcb0c1 | ||
|
|
98c9e67625 | ||
|
|
aeef66ce35 | ||
|
|
8cff66e8c6 | ||
|
|
10a04acf41 | ||
|
|
9923a4c4ff | ||
|
|
0dafa9e229 | ||
|
|
e83e8a8f1c | ||
|
|
72aa768235 | ||
|
|
65c74e3976 | ||
|
|
cdac34efea | ||
|
|
03fef3106d | ||
|
|
d598d0a4db | ||
|
|
ab22e1b3a9 | ||
|
|
26d520af3c | ||
|
|
fb333f3641 | ||
|
|
1cc65a47eb | ||
|
|
8d56c52991 | ||
|
|
4b88b9eed1 | ||
|
|
462b91fb08 | ||
|
|
b65f4ff963 | ||
|
|
8d27b48225 | ||
|
|
e2623c5e82 | ||
|
|
acdae42fc5 | ||
|
|
451aac806e | ||
|
|
586e6178b4 | ||
|
|
1201761ff3 | ||
|
|
bdf68f092e | ||
|
|
a179f87d54 | ||
|
|
b2944a12de | ||
|
|
bfcb36927c | ||
|
|
ccd21d5254 | ||
|
|
a7b8448107 | ||
|
|
e934be2d99 | ||
|
|
015b875a9e | ||
|
|
1247ff2543 | ||
|
|
dc831fb3f6 | ||
|
|
94c0e947f5 | ||
|
|
ed9bc835a2 | ||
|
|
2eb2e52a79 | ||
|
|
14f6f88526 | ||
|
|
1f78c74085 | ||
|
|
c494649dde | ||
|
|
460f3aebe9 | ||
|
|
d4b215a66b | ||
|
|
1a13387012 | ||
|
|
291c36df05 | ||
|
|
bed2c8a371 | ||
|
|
e65ca4ccac | ||
|
|
f9e6933840 | ||
|
|
5134fb2ec1 | ||
|
|
3a86a69964 | ||
|
|
c6fd3c47a4 | ||
|
|
a365fa6109 | ||
|
|
160451b210 | ||
|
|
2f6e3cc09d | ||
|
|
d05cc7ccec | ||
|
|
ccfd4acbda | ||
|
|
6a6084ed0e | ||
|
|
0dbb780a2f | ||
|
|
e6efa6e13e | ||
|
|
76768120d4 | ||
|
|
7d6ff83760 | ||
|
|
5bec0d2d98 | ||
|
|
aad05325a6 | ||
|
|
6e7f1bc257 | ||
|
|
634d0848c8 | ||
|
|
b7e1059227 | ||
|
|
e7904fa67a | ||
|
|
e38bc7cbce | ||
|
|
b211f8a096 | ||
|
|
b4a1a6c688 | ||
|
|
6cb4b790b9 | ||
|
|
a245bdbc2a | ||
|
|
e63451a9e7 | ||
|
|
e552607c95 | ||
|
|
c7f1c5e29c | ||
|
|
37b6e22321 | ||
|
|
6e6ae18aab | ||
|
|
9f3cda0ac3 | ||
|
|
f646975c36 | ||
|
|
801cae13ac | ||
|
|
f1ae502b1f | ||
|
|
f2e34d4836 | ||
|
|
3c6a8d718f | ||
|
|
08eb28f7b8 | ||
|
|
24509a21d4 | ||
|
|
4f41a10fef | ||
|
|
26aa8b69f9 | ||
|
|
819db1524f | ||
|
|
8ad7d06ec6 | ||
|
|
606898f569 | ||
|
|
76c6adf1cf | ||
|
|
e504c3cd46 | ||
|
|
884b59a0b3 | ||
|
|
a32dedd16c | ||
|
|
ff2b37f6e3 |
144
build/Jamfile.v2
Normal file
@@ -0,0 +1,144 @@
|
||||
# Copyright David Abrahams 2001-2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import os ;
|
||||
import indirect ;
|
||||
import modules ;
|
||||
import feature ;
|
||||
|
||||
import python ;
|
||||
|
||||
if ! [ python.configured ] && ! ( --without-python in [ modules.peek : ARGV ] )
|
||||
{
|
||||
# Attempt default configuration of python
|
||||
import toolset : using ;
|
||||
using python ;
|
||||
|
||||
if ! [ python.configured ]
|
||||
{
|
||||
ECHO "WARNING: No python installation configured and autoconfiguration" ;
|
||||
ECHO " failed. See http://www.boost.org/libs/python/doc/building.html" ;
|
||||
ECHO " for configuration instructions or pass --without-python to" ;
|
||||
ECHO " suppress this message and silently skip all Boost.Python targets" ;
|
||||
}
|
||||
}
|
||||
|
||||
rule find-py3-version
|
||||
{
|
||||
local versions = [ feature.values python ] ;
|
||||
local py3ver ;
|
||||
for local v in $(versions)
|
||||
{
|
||||
if $(v) >= 3.0
|
||||
{
|
||||
py3ver = $(v) ;
|
||||
}
|
||||
}
|
||||
return $(py3ver) ;
|
||||
}
|
||||
|
||||
py3-version = [ find-py3-version ] ;
|
||||
|
||||
project boost/python
|
||||
: source-location ../src
|
||||
: requirements
|
||||
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
|
||||
<tag>@$(__name__).tag
|
||||
;
|
||||
|
||||
rule tag ( name : type ? : property-set )
|
||||
{
|
||||
local result = $(name) ;
|
||||
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
|
||||
{
|
||||
if $(name) = boost_python && $(PYTHON_ID)
|
||||
{
|
||||
result = $(result)-$(PYTHON_ID) ;
|
||||
}
|
||||
}
|
||||
|
||||
# forward to the boost tagging rule
|
||||
return [ indirect.call $(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
|
||||
$(result) : $(type) : $(property-set) ] ;
|
||||
}
|
||||
|
||||
rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
|
||||
rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
|
||||
|
||||
rule lib_boost_python ( is-py3 ? )
|
||||
{
|
||||
|
||||
lib [ cond $(is-py3) : boost_python3 : boost_python ]
|
||||
: # sources
|
||||
numeric.cpp
|
||||
list.cpp
|
||||
long.cpp
|
||||
dict.cpp
|
||||
tuple.cpp
|
||||
str.cpp
|
||||
slice.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/stl_iterator.cpp
|
||||
object_protocol.cpp
|
||||
object_operators.cpp
|
||||
wrapper.cpp
|
||||
import.cpp
|
||||
exec.cpp
|
||||
object/function_doc_signature.cpp
|
||||
: # requirements
|
||||
<link>static:<define>BOOST_PYTHON_STATIC_LIB
|
||||
<define>BOOST_PYTHON_SOURCE
|
||||
|
||||
# On Windows, all code using Python has to link to the Python
|
||||
# import library.
|
||||
#
|
||||
# On *nix we never link libboost_python to libpython. When
|
||||
# extending Python, all Python symbols are provided by the
|
||||
# Python interpreter executable. When embedding Python, the
|
||||
# client executable is expected to explicitly link to
|
||||
# /python//python (the target representing libpython) itself.
|
||||
#
|
||||
# python_for_extensions is a target defined by Boost.Build to
|
||||
# provide the Python include paths, and on Windows, the Python
|
||||
# import library, as usage requirements.
|
||||
[ cond [ python.configured ] : <library>/python//python_for_extensions ]
|
||||
|
||||
# we prevent building when there is no python available
|
||||
# as it's not possible anyway, and to cause dependents to
|
||||
# fail to build
|
||||
[ unless [ python.configured ] : <build>no ]
|
||||
|
||||
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
|
||||
[ cond $(is-py3) : <python>$(py3-version) ]
|
||||
: # default build
|
||||
<link>shared
|
||||
: # usage requirements
|
||||
<link>static:<define>BOOST_PYTHON_STATIC_LIB
|
||||
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
lib_boost_python ;
|
||||
boost-install boost_python ;
|
||||
|
||||
if $(py3-version)
|
||||
{
|
||||
lib_boost_python yes ;
|
||||
boost-install boost_python3 ;
|
||||
}
|
||||
@@ -1,241 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="bpl_static" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=bpl_static - Win32 DebugPython
|
||||
!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 "bpl_static.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 "bpl_static.mak" CFG="bpl_static - Win32 DebugPython"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "bpl_static - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "bpl_static - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "bpl_static - Win32 DebugPython" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "bpl_static - 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 "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W4 /WX /GR /GX /O2 /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "bpl_static - 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 "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W4 /WX /Gm- /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "bpl_static - Win32 DebugPython"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "bpl_static___Win32_DebugPython"
|
||||
# PROP BASE Intermediate_Dir "bpl_static___Win32_DebugPython"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "DebugPython"
|
||||
# PROP Intermediate_Dir "DebugPython"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MDd /W4 /WX /Gm /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W4 /WX /Gm- /GR /GX /Zi /Od /I "..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "BOOST_DEBUG_PYTHON" /FR /YX /FD /GZ /EHs /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "bpl_static - Win32 Release"
|
||||
# Name "bpl_static - Win32 Debug"
|
||||
# Name "bpl_static - Win32 DebugPython"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\classes.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\conversions.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\extension_class.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\functions.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\init_function.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\module_builder.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\objects.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\src\types.cpp
|
||||
# ADD CPP /W3
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\base_object.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\callback.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\caller.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\cast.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\class_builder.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\classes.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\config.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\conversions.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\errors.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\extension_class.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\functions.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\init_function.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\module_builder.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\none.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\objects.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\operators.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\reference.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\signatures.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\singleton.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\types.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\boost\python\detail\wrap_python.hpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
108
build/build.dsw
@@ -1,108 +0,0 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "bpl_static"=.\bpl_static.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "example1"=.\example1\example1.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name bpl_static
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "getting_started1"=.\getting_started1\getting_started1.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name bpl_static
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "getting_started2"=.\getting_started2\getting_started2.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
getting_started2
|
||||
.\getting_started2
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name bpl_static
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "rwgk1"=.\rwgk1\rwgk1.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name bpl_static
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "test"=.\test\test.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name bpl_static
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
BIN
build/build.opt
@@ -1,58 +0,0 @@
|
||||
# Revision History:
|
||||
# 17 Apr 01 include cross-module support, compile getting_started1 (R.W. Grosse-Kunstleve) UNTESTED!
|
||||
# 06 Mar 01 Fixed typo in use of "PYTHON_LIB" (Dave Abrahams)
|
||||
# 04 Mar 01 Changed library name to libboost_python.a (David Abrahams)
|
||||
|
||||
LIBSRC = \
|
||||
classes.cpp \
|
||||
conversions.cpp \
|
||||
cross_module.cpp \
|
||||
extension_class.cpp \
|
||||
functions.cpp \
|
||||
init_function.cpp \
|
||||
module_builder.cpp \
|
||||
objects.cpp \
|
||||
types.cpp
|
||||
|
||||
LIBOBJ = $(LIBSRC:.cpp=.o)
|
||||
OBJ = $(LIBOBJ)
|
||||
|
||||
|
||||
ifeq "$(OS)" "Windows_NT"
|
||||
PYTHON_LIB=c:/tools/python/libs/python15.lib
|
||||
INC = -Ic:/cygnus/usr/include/g++-3 -Ic:/cygnus/usr/include -Ic:/boost -Ic:/tools/python/include
|
||||
MODULE_EXTENSION=dll
|
||||
else
|
||||
INC = -I/usr/local/include/python1.5
|
||||
MODULE_EXTENSION=so
|
||||
endif
|
||||
|
||||
%.o: ../src/%.cpp
|
||||
como --pic $(INC) -o $*.o -c $<
|
||||
|
||||
%.d: ../src/%.cpp
|
||||
@echo creating $@
|
||||
@set -e; como -M $(INC) -c $< \
|
||||
| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
|
||||
[ -s $@ ] || rm -f $@
|
||||
|
||||
getting_started1: getting_started1.o libboost_python.a
|
||||
como-dyn-link -o ../example/getting_started1.$(MODULE_EXTENSION) $(PYTHON_LIB) getting_started1.o -L. -lboost_python
|
||||
ln -s ../test/doctest.py ../example
|
||||
python ../example/test_getting_started1.py
|
||||
|
||||
getting_started1.o: ../example/getting_started1.cpp
|
||||
como --pic $(INC) -o $*.o -c $<
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out
|
||||
|
||||
libboost_python.a: $(LIBOBJ)
|
||||
rm -f libboost_python.a
|
||||
ar cq libboost_python.a $(LIBOBJ)
|
||||
|
||||
DEP = $(OBJ:.o=.d)
|
||||
|
||||
ifneq "$(MAKECMDGOALS)" "clean"
|
||||
include $(DEP)
|
||||
endif
|
||||
@@ -1,136 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="example1" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=example1 - Win32 DebugPython
|
||||
!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 "example1.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 "example1.mak" CFG="example1 - Win32 DebugPython"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "example1 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "example1 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "example1 - Win32 DebugPython" (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)" == "example1 - 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 "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /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 gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/hello.dll" /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "example1 - 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 "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /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 gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"Debug/hello.dll" /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "example1 - Win32 DebugPython"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "example1___Win32_DebugPython"
|
||||
# PROP BASE Intermediate_Dir "example1___Win32_DebugPython"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "DebugPython"
|
||||
# PROP Intermediate_Dir "DebugPython"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /EHs /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /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 /incremental:no /debug /machine:I386 /out:"Debug/hello.dll" /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
# ADD 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 /incremental:no /debug /machine:I386 /out:"DebugPython/hello_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\PCbuild"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "example1 - Win32 Release"
|
||||
# Name "example1 - Win32 Debug"
|
||||
# Name "example1 - Win32 DebugPython"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\example\example1.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# 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
|
||||
132
build/filemgr.py
@@ -1,132 +0,0 @@
|
||||
# Revision history:
|
||||
# 12 Apr 01 use os.path, shutil
|
||||
# Initial version: R.W. Grosse-Kunstleve
|
||||
|
||||
bpl_src = "/libs/python/src"
|
||||
bpl_tst = "/libs/python/test"
|
||||
bpl_exa = "/libs/python/example"
|
||||
files = (
|
||||
bpl_src + "/classes.cpp",
|
||||
bpl_src + "/conversions.cpp",
|
||||
bpl_src + "/extension_class.cpp",
|
||||
bpl_src + "/functions.cpp",
|
||||
bpl_src + "/init_function.cpp",
|
||||
bpl_src + "/module_builder.cpp",
|
||||
bpl_src + "/objects.cpp",
|
||||
bpl_src + "/types.cpp",
|
||||
bpl_src + "/cross_module.cpp",
|
||||
bpl_tst + "/comprehensive.cpp",
|
||||
bpl_tst + "/comprehensive.hpp",
|
||||
bpl_tst + "/comprehensive.py",
|
||||
bpl_tst + "/doctest.py",
|
||||
bpl_exa + "/abstract.cpp",
|
||||
bpl_exa + "/getting_started1.cpp",
|
||||
bpl_exa + "/getting_started2.cpp",
|
||||
bpl_exa + "/simple_vector.cpp",
|
||||
bpl_exa + "/do_it_yourself_converters.cpp",
|
||||
bpl_exa + "/pickle1.cpp",
|
||||
bpl_exa + "/pickle2.cpp",
|
||||
bpl_exa + "/pickle3.cpp",
|
||||
bpl_exa + "/test_abstract.py",
|
||||
bpl_exa + "/test_getting_started1.py",
|
||||
bpl_exa + "/test_getting_started2.py",
|
||||
bpl_exa + "/test_simple_vector.py",
|
||||
bpl_exa + "/test_do_it_yourself_converters.py",
|
||||
bpl_exa + "/test_pickle1.py",
|
||||
bpl_exa + "/test_pickle2.py",
|
||||
bpl_exa + "/test_pickle3.py",
|
||||
bpl_exa + "/noncopyable.h",
|
||||
bpl_exa + "/noncopyable_export.cpp",
|
||||
bpl_exa + "/noncopyable_import.cpp",
|
||||
bpl_exa + "/dvect.h",
|
||||
bpl_exa + "/dvect.cpp",
|
||||
bpl_exa + "/dvect_conversions.cpp",
|
||||
bpl_exa + "/dvect_defs.cpp",
|
||||
bpl_exa + "/ivect.h",
|
||||
bpl_exa + "/ivect.cpp",
|
||||
bpl_exa + "/ivect_conversions.cpp",
|
||||
bpl_exa + "/ivect_defs.cpp",
|
||||
bpl_exa + "/tst_noncopyable.py",
|
||||
bpl_exa + "/tst_dvect1.py",
|
||||
bpl_exa + "/tst_dvect2.py",
|
||||
bpl_exa + "/tst_ivect1.py",
|
||||
bpl_exa + "/tst_ivect2.py",
|
||||
bpl_exa + "/test_cross_module.py",
|
||||
)
|
||||
|
||||
defs = (
|
||||
"boost_python_test",
|
||||
"abstract",
|
||||
"getting_started1",
|
||||
"getting_started2",
|
||||
"simple_vector",
|
||||
"do_it_yourself_converters",
|
||||
"pickle1",
|
||||
"pickle2",
|
||||
"pickle3",
|
||||
"noncopyable_export",
|
||||
"noncopyable_import",
|
||||
"ivect",
|
||||
"dvect",
|
||||
)
|
||||
|
||||
if (__name__ == "__main__"):
|
||||
|
||||
import sys, os, shutil
|
||||
|
||||
path = sys.argv[1]
|
||||
mode = sys.argv[2]
|
||||
if (not mode in ("softlinks", "unlink", "cp", "rm", "copy", "del")):
|
||||
raise RuntimeError, \
|
||||
"usage: python filemgr.py path <softlinks|unlink|cp|rm|copy|del>"
|
||||
|
||||
if (mode in ("cp", "copy")):
|
||||
for fn in files:
|
||||
f = os.path.basename(fn)
|
||||
print "Copying: " + f
|
||||
shutil.copy(path + fn, ".")
|
||||
|
||||
elif (mode == "softlinks"):
|
||||
for fn in files:
|
||||
f = os.path.basename(fn)
|
||||
if (os.path.exists(f)):
|
||||
print "File exists: " + f
|
||||
else:
|
||||
print "Linking: " + f
|
||||
os.symlink(path + fn, f)
|
||||
|
||||
elif (mode in ("rm", "del")):
|
||||
for fn in files:
|
||||
f = os.path.basename(fn)
|
||||
if (os.path.exists(f)):
|
||||
print "Removing: " + f
|
||||
try: os.unlink(f)
|
||||
except: pass
|
||||
|
||||
elif (mode == "unlink"):
|
||||
for fn in files:
|
||||
f = os.path.basename(fn)
|
||||
if (os.path.exists(f)):
|
||||
if (os.path.islink(f)):
|
||||
print "Unlinking: " + f
|
||||
try: os.unlink(f)
|
||||
except: pass
|
||||
else:
|
||||
print "Not a softlink: " + f
|
||||
|
||||
if (mode in ("softlinks", "cp", "copy")):
|
||||
for d in defs:
|
||||
fn = d + ".def"
|
||||
print "Creating: " + fn
|
||||
f = open(fn, "w")
|
||||
f.write("EXPORTS\n")
|
||||
f.write("\tinit" + d + "\n")
|
||||
f.close()
|
||||
|
||||
if (mode in ("unlink", "rm", "del")):
|
||||
for d in defs:
|
||||
fn = d + ".def"
|
||||
if (os.path.exists(fn)):
|
||||
print "Removing: " + fn
|
||||
try: os.unlink(fn)
|
||||
except: pass
|
||||
@@ -1,87 +0,0 @@
|
||||
# Revision History
|
||||
|
||||
# 17 Apr 01 include cross-module support, compile getting_started1 (R.W. Grosse-Kunstleve)
|
||||
# 17 Apr 01 build shared library (patch provided by Dan Nuffer)
|
||||
# 04 Mar 01 Changed library name to libboost_python.a, various cleanups,
|
||||
# attempted Cygwin compatibility. Still needs testing on Linux
|
||||
# (David Abrahams)
|
||||
|
||||
|
||||
LIBSRC = \
|
||||
classes.cpp \
|
||||
conversions.cpp \
|
||||
cross_module.cpp \
|
||||
extension_class.cpp \
|
||||
functions.cpp \
|
||||
init_function.cpp \
|
||||
module_builder.cpp \
|
||||
objects.cpp \
|
||||
types.cpp
|
||||
|
||||
LIBOBJ = $(LIBSRC:.cpp=.o)
|
||||
OBJ = $(LIBOBJ)
|
||||
|
||||
LIBNAME = libboost_python
|
||||
# libpython2.0.dll
|
||||
|
||||
ifeq "$(OS)" "Windows_NT"
|
||||
ROOT=c:/cygnus
|
||||
INC = -Ic:/cygnus/usr/include/g++-3 -Ic:/cygnus/usr/include -Ic:/boost -I$(PYTHON_INC)
|
||||
MODULE_EXTENSION=dll
|
||||
PYTHON_LIB=c:/cygnus/usr/local/lib/python2.0/config/libpython2.0.dll.a
|
||||
SHARED_LIB = $(LIBNAME).dll
|
||||
else
|
||||
PYTHON_INC=$(ROOT)/usr/local/Python-2.0/include/python2.0
|
||||
BOOST_INC=../../..
|
||||
INC = -I$(BOOST_INC) -I$(PYTHON_INC)
|
||||
MODULE_EXTENSION=so
|
||||
VERSION=1
|
||||
SHARED_LIB = $(LIBNAME).so.$(VERSION)
|
||||
endif
|
||||
|
||||
%.o: ../src/%.cpp
|
||||
g++ -fPIC -Wall -W $(INC) $(CXXFLAGS) -o $*.o -c $<
|
||||
|
||||
%.d: ../src/%.cpp
|
||||
@echo creating $@
|
||||
@set -e; g++ -M $(INC) -c $< \
|
||||
| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
|
||||
[ -s $@ ] || rm -f $@
|
||||
|
||||
|
||||
PYTHON = python
|
||||
|
||||
all: test $(SHARED_LIB) getting_started1
|
||||
|
||||
test: comprehensive.o $(LIBNAME).a $(SHARED_LIB)
|
||||
g++ $(CXXFLAGS) -shared -o ../test/boost_python_test.$(MODULE_EXTENSION) comprehensive.o -L. -lboost_python $(PYTHON_LIB)
|
||||
$(PYTHON) ../test/comprehensive.py
|
||||
|
||||
comprehensive.o: ../test/comprehensive.cpp
|
||||
g++ $(CXXFLAGS) --template-depth-32 -fPIC -Wall -W $(INC) -o $*.o -c $<
|
||||
|
||||
|
||||
getting_started1: getting_started1.o $(LIBNAME).a
|
||||
g++ $(CXXFLAGS) -shared -o ../example/getting_started1.$(MODULE_EXTENSION) getting_started1.o -L. -lboost_python $(PYTHON_LIB)
|
||||
ln -s ../test/doctest.py ../example
|
||||
$(PYTHON) ../example/test_getting_started1.py
|
||||
|
||||
getting_started1.o: ../example/getting_started1.cpp
|
||||
g++ $(CXXFLAGS) --template-depth-32 -fPIC -Wall -W $(INC) -o $*.o -c $<
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out
|
||||
|
||||
$(LIBNAME).a: $(LIBOBJ)
|
||||
rm -f $@
|
||||
ar cqs $@ $(LIBOBJ)
|
||||
|
||||
$(SHARED_LIB): $(LIBOBJ)
|
||||
g++ $(CXXFLAGS) -shared -o $@ -Wl,--soname=$(LIBNAME).$(MODULE_EXTENSION)
|
||||
|
||||
DEP = $(OBJ:.o=.d)
|
||||
|
||||
ifneq "$(MAKECMDGOALS)" "clean"
|
||||
include $(DEP)
|
||||
endif
|
||||
@@ -1,136 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="getting_started1" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=getting_started1 - Win32 DebugPython
|
||||
!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 "getting_started1.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 "getting_started1.mak" CFG="getting_started1 - Win32 DebugPython"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "getting_started1 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "getting_started1 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "getting_started1 - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=xicl6.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "getting_started1 - 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 "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=xilink6.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 /subsystem:windows /dll /machine:I386
|
||||
# ADD 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 /subsystem:windows /dll /machine:I386 /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "getting_started1 - 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 "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /GR /GX /ZI /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=xilink6.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 /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD 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 /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "getting_started1 - Win32 DebugPython"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "DebugPython"
|
||||
# PROP BASE Intermediate_Dir "DebugPython"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "DebugPython"
|
||||
# PROP Intermediate_Dir "DebugPython"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=xilink6.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 /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD 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 /incremental:no /pdb:"DebugPython/boost_python_test_d.pdb" /debug /machine:I386 /out:"DebugPython/getting_started1_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\PCbuild"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "getting_started1 - Win32 Release"
|
||||
# Name "getting_started1 - Win32 Debug"
|
||||
# Name "getting_started1 - Win32 DebugPython"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\example\getting_started1.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# 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
|
||||
@@ -1,135 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="getting_started2" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=getting_started2 - Win32 DebugPython
|
||||
!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 "getting_started2.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 "getting_started2.mak" CFG="getting_started2 - Win32 DebugPython"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "getting_started2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "getting_started2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "getting_started2 - Win32 DebugPython" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName "getting_started2"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=xicl6.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "getting_started2 - 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 "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=xilink6.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 /subsystem:windows /dll /machine:I386
|
||||
# ADD 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 /subsystem:windows /dll /machine:I386 /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "getting_started2 - 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 "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=xilink6.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 /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD 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 /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "getting_started2 - Win32 DebugPython"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "getting_started2___Win32_DebugPython"
|
||||
# PROP BASE Intermediate_Dir "getting_started2___Win32_DebugPython"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "getting_started2___Win32_DebugPython"
|
||||
# PROP Intermediate_Dir "getting_started2___Win32_DebugPython"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /FR /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=xilink6.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 /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD 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 /subsystem:windows /dll /debug /machine:I386 /out:"DebugPython/getting_started2_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\pcbuild"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "getting_started2 - Win32 Release"
|
||||
# Name "getting_started2 - Win32 Debug"
|
||||
# Name "getting_started2 - Win32 DebugPython"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\example\getting_started2.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# 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
|
||||
@@ -1,160 +0,0 @@
|
||||
# Usage:
|
||||
#
|
||||
# Create a new empty directory anywhere (preferably not in the boost tree).
|
||||
# Copy this Makefile to that new directory and rename it to "Makefile"
|
||||
# Adjust the pathnames below.
|
||||
#
|
||||
# make softlinks Create softlinks to source code and tests
|
||||
# make Compile all sources
|
||||
# make test Run doctest tests
|
||||
# make clean Remove all object files
|
||||
# make unlink Remove softlinks
|
||||
#
|
||||
# Revision history:
|
||||
# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve)
|
||||
# Initial version: R.W. Grosse-Kunstleve
|
||||
|
||||
ROOT=$(HOME)
|
||||
BOOST=$(ROOT)/boost
|
||||
|
||||
PYEXE=/usr/local/Python-1.5.2/bin/python
|
||||
PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||
#PYEXE=/usr/local/Python-2.0/bin/python
|
||||
#PYINC=-I/usr/local/Python-2.0/include/python2.0
|
||||
STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers
|
||||
|
||||
STDOPTS=
|
||||
WARNOPTS=-woff 1001,1234,1682
|
||||
OPTOPTS=-g
|
||||
|
||||
CPP=CC -LANG:std -n32 -mips4
|
||||
CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \
|
||||
$(STDOPTS) $(WARNOPTS) $(OPTOPTS)
|
||||
MAKEDEP=-M
|
||||
|
||||
LD=CC -LANG:std -n32 -mips4
|
||||
LDOPTS=-shared
|
||||
|
||||
OBJ=classes.o conversions.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o cross_module.o
|
||||
DEPOBJ=$(OBJ) \
|
||||
comprehensive.o \
|
||||
abstract.o \
|
||||
getting_started1.o getting_started2.o \
|
||||
simple_vector.o \
|
||||
do_it_yourself_converters.o \
|
||||
pickle1.o pickle2.o pickle3.o \
|
||||
noncopyable_export.o noncopyable_import.o \
|
||||
ivect.o dvect.o
|
||||
|
||||
.SUFFIXES: .o .cpp
|
||||
|
||||
all: libboost_python.a \
|
||||
boost_python_test.so \
|
||||
abstract.so \
|
||||
getting_started1.so getting_started2.so \
|
||||
simple_vector.so \
|
||||
do_it_yourself_converters.so \
|
||||
pickle1.so pickle2.so pickle3.so \
|
||||
noncopyable_export.so noncopyable_import.so \
|
||||
ivect.so dvect.so
|
||||
|
||||
libboost_python.a: $(OBJ)
|
||||
rm -f libboost_python.a
|
||||
$(CPP) -ar -o libboost_python.a $(OBJ)
|
||||
|
||||
boost_python_test.so: $(OBJ) comprehensive.o
|
||||
$(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm
|
||||
|
||||
abstract.so: $(OBJ) abstract.o
|
||||
$(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so
|
||||
|
||||
getting_started1.so: $(OBJ) getting_started1.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so
|
||||
|
||||
getting_started2.so: $(OBJ) getting_started2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so
|
||||
|
||||
simple_vector.so: $(OBJ) simple_vector.o
|
||||
$(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so
|
||||
|
||||
do_it_yourself_converters.so: $(OBJ) do_it_yourself_converters.o
|
||||
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.o -o do_it_yourself_converters.so
|
||||
|
||||
pickle1.so: $(OBJ) pickle1.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so
|
||||
|
||||
pickle2.so: $(OBJ) pickle2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so
|
||||
|
||||
pickle3.so: $(OBJ) pickle3.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so
|
||||
|
||||
noncopyable_export.so: $(OBJ) noncopyable_export.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \
|
||||
noncopyable_export.o -o noncopyable_export.so
|
||||
|
||||
noncopyable_import.so: $(OBJ) noncopyable_import.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \
|
||||
noncopyable_import.o -o noncopyable_import.so
|
||||
|
||||
ivect.so: $(OBJ) ivect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so
|
||||
|
||||
dvect.so: $(OBJ) dvect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
||||
|
||||
.cpp.o:
|
||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||
|
||||
test:
|
||||
$(PYEXE) comprehensive.py
|
||||
$(PYEXE) test_abstract.py
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_converters.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
||||
rm -f comprehensive.o boost_python_test.so
|
||||
rm -f abstract.o abstract.so
|
||||
rm -f getting_started1.o getting_started1.so
|
||||
rm -f getting_started2.o getting_started2.so
|
||||
rm -f simple_vector.o simple_vector.so
|
||||
rm -f do_it_yourself_converters.o do_it_yourself_converters.so
|
||||
rm -f pickle1.o pickle1.so
|
||||
rm -f pickle2.o pickle2.so
|
||||
rm -f pickle3.o pickle3.so
|
||||
rm -f noncopyable_export.o noncopyable_export.so
|
||||
rm -f noncopyable_import.o noncopyable_import.so
|
||||
rm -f ivect.o ivect.so
|
||||
rm -f dvect.o dvect.so
|
||||
rm -f so_locations *.pyc
|
||||
rm -rf ii_files
|
||||
|
||||
softlinks:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks
|
||||
|
||||
unlink:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink
|
||||
|
||||
cp:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp
|
||||
|
||||
rm:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm
|
||||
|
||||
depend:
|
||||
@ cat Makefile.nodepend; \
|
||||
for obj in $(DEPOBJ); \
|
||||
do \
|
||||
bn=`echo "$$obj" | cut -d. -f1`; \
|
||||
$(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \
|
||||
done
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
# Usage:
|
||||
#
|
||||
# Create a new empty directory anywhere (preferably not in the boost tree).
|
||||
# Copy this Makefile to that new directory and rename it to "Makefile"
|
||||
# Adjust the pathnames below.
|
||||
#
|
||||
# make softlinks Create softlinks to source code and tests
|
||||
# make Compile all sources
|
||||
# make test Run doctest tests
|
||||
# make clean Remove all object files
|
||||
# make unlink Remove softlinks
|
||||
#
|
||||
# Revision history:
|
||||
# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve)
|
||||
# Initial version: R.W. Grosse-Kunstleve
|
||||
|
||||
ROOT=$(HOME)
|
||||
BOOST=$(ROOT)/boost
|
||||
|
||||
PYEXE=PYTHONPATH=. /usr/bin/python
|
||||
PYINC=-I/usr/include/python1.5
|
||||
#PYEXE=/usr/local/Python-1.5.2/bin/python
|
||||
#PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||
#PYEXE=/usr/local/Python-2.0/bin/python
|
||||
#PYINC=-I/usr/local/Python-2.0/include/python2.0
|
||||
|
||||
STDOPTS=-fPIC -ftemplate-depth-21
|
||||
WARNOPTS=
|
||||
OPTOPTS=-g
|
||||
|
||||
CPP=g++
|
||||
CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \
|
||||
$(STDOPTS) $(WARNOPTS) $(OPTOPTS)
|
||||
MAKEDEP=-M
|
||||
|
||||
LD=$(CPP)
|
||||
LDOPTS=-shared
|
||||
|
||||
OBJ=classes.o conversions.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o cross_module.o
|
||||
DEPOBJ=$(OBJ) \
|
||||
comprehensive.o \
|
||||
abstract.o \
|
||||
getting_started1.o getting_started2.o \
|
||||
simple_vector.o \
|
||||
do_it_yourself_converters.o \
|
||||
pickle1.o pickle2.o pickle3.o \
|
||||
noncopyable_export.o noncopyable_import.o \
|
||||
ivect.o dvect.o
|
||||
|
||||
.SUFFIXES: .o .cpp
|
||||
|
||||
all: libboost_python.a \
|
||||
boost_python_test.so \
|
||||
abstract.so \
|
||||
getting_started1.so getting_started2.so \
|
||||
simple_vector.so \
|
||||
do_it_yourself_converters.so \
|
||||
pickle1.so pickle2.so pickle3.so \
|
||||
noncopyable_export.so noncopyable_import.so \
|
||||
ivect.so dvect.so
|
||||
|
||||
libboost_python.a: $(OBJ)
|
||||
rm -f libboost_python.a
|
||||
ar r libboost_python.a $(OBJ)
|
||||
|
||||
boost_python_test.so: $(OBJ) comprehensive.o
|
||||
$(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm
|
||||
|
||||
abstract.so: $(OBJ) abstract.o
|
||||
$(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so
|
||||
|
||||
getting_started1.so: $(OBJ) getting_started1.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so
|
||||
|
||||
getting_started2.so: $(OBJ) getting_started2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so
|
||||
|
||||
simple_vector.so: $(OBJ) simple_vector.o
|
||||
$(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so
|
||||
|
||||
do_it_yourself_converters.so: $(OBJ) do_it_yourself_converters.o
|
||||
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.o -o do_it_yourself_converters.so
|
||||
|
||||
pickle1.so: $(OBJ) pickle1.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so
|
||||
|
||||
pickle2.so: $(OBJ) pickle2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so
|
||||
|
||||
pickle3.so: $(OBJ) pickle3.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so
|
||||
|
||||
noncopyable_export.so: $(OBJ) noncopyable_export.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \
|
||||
noncopyable_export.o -o noncopyable_export.so
|
||||
|
||||
noncopyable_import.so: $(OBJ) noncopyable_import.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \
|
||||
noncopyable_import.o -o noncopyable_import.so
|
||||
|
||||
ivect.so: $(OBJ) ivect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so
|
||||
|
||||
dvect.so: $(OBJ) dvect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
||||
|
||||
.cpp.o:
|
||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||
|
||||
test:
|
||||
$(PYEXE) comprehensive.py
|
||||
$(PYEXE) test_abstract.py
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_converters.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
||||
rm -f comprehensive.o boost_python_test.so
|
||||
rm -f abstract.o abstract.so
|
||||
rm -f getting_started1.o getting_started1.so
|
||||
rm -f getting_started2.o getting_started2.so
|
||||
rm -f simple_vector.o simple_vector.so
|
||||
rm -f do_it_yourself_converters.o do_it_yourself_converters.so
|
||||
rm -f pickle1.o pickle1.so
|
||||
rm -f pickle2.o pickle2.so
|
||||
rm -f pickle3.o pickle3.so
|
||||
rm -f noncopyable_export.o noncopyable_export.so
|
||||
rm -f noncopyable_import.o noncopyable_import.so
|
||||
rm -f ivect.o ivect.so
|
||||
rm -f dvect.o dvect.so
|
||||
rm -f so_locations *.pyc
|
||||
|
||||
softlinks:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks
|
||||
|
||||
unlink:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink
|
||||
|
||||
cp:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp
|
||||
|
||||
rm:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm
|
||||
|
||||
depend:
|
||||
@ cat Makefile.nodepend; \
|
||||
for obj in $(DEPOBJ); \
|
||||
do \
|
||||
bn=`echo "$$obj" | cut -d. -f1`; \
|
||||
$(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \
|
||||
done
|
||||
|
||||
@@ -1,189 +0,0 @@
|
||||
# Usage:
|
||||
#
|
||||
# make copy Copy the sources and tests
|
||||
# make Compile all sources
|
||||
# make test Run doctest tests
|
||||
# make clean Remove all object files
|
||||
# make del Remove the sources and tests
|
||||
#
|
||||
# Revision history:
|
||||
# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve)
|
||||
# Initial version: R.W. Grosse-Kunstleve
|
||||
|
||||
# To install mingw32, follow instructions at:
|
||||
# http://starship.python.net/crew/kernr/mingw32/Notes.html
|
||||
# In particular, install:
|
||||
# ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/mingw32/gcc-2.95.2/gcc-2.95.2-msvcrt.exe
|
||||
# ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/mingw32/gcc-2.95.2/fixes/quote-fix-msvcrt.exe
|
||||
# http://starship.python.net/crew/kernr/mingw32/Python-1.5.2-mingw32.zip
|
||||
# Unpack the first two archives in the default locations and update your PATH.
|
||||
# Unpack the third archive in \usr.
|
||||
|
||||
# Note: comprehensive.cpp generates compiler errors and later crashes.
|
||||
# L:\boost\boost\python\detail\extension_class.hpp:643: warning:
|
||||
# alignment of `vtable for class
|
||||
# boost::python::detail::held_instance<bpl_test::Derived1>'
|
||||
# is greater than maximum object file alignment. Using 16.
|
||||
# Could this be fixed with compiler options?
|
||||
# -fhuge-objects looks interesting, but requires recompiling the C++ library.
|
||||
# (what exactly does that mean?)
|
||||
# -fvtable-thunks eliminates the compiler warning, but
|
||||
# "import boost_python_test" still causes a crash.
|
||||
|
||||
ROOT=L:
|
||||
BOOST_WIN="$(ROOT)\boost"
|
||||
BOOST_UNIX=$(HOME)/boost
|
||||
|
||||
PYEXE="C:\Program files\Python\python.exe"
|
||||
PYINC=-I"C:\usr\include\python1.5"
|
||||
PYLIB="C:\usr\lib\libpython15.a"
|
||||
|
||||
STDOPTS=-ftemplate-depth-21
|
||||
WARNOPTS=
|
||||
OPTOPTS=-g
|
||||
|
||||
CPP=g++
|
||||
CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST_WIN) $(PYINC) \
|
||||
$(STDOPTS) $(WARNOPTS) $(OPTOPTS)
|
||||
|
||||
LD=g++
|
||||
LDOPTS=-shared
|
||||
|
||||
OBJ=classes.o conversions.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o cross_module.o
|
||||
|
||||
.SUFFIXES: .o .cpp
|
||||
|
||||
all: libboost_python.a \
|
||||
abstract.pyd \
|
||||
getting_started1.pyd getting_started2.pyd \
|
||||
simple_vector.pyd \
|
||||
do_it_yourself_converters.pyd \
|
||||
pickle1.pyd pickle2.pyd pickle3.pyd \
|
||||
noncopyable_export.pyd noncopyable_import.pyd \
|
||||
ivect.pyd dvect.pyd
|
||||
|
||||
libboost_python.a: $(OBJ)
|
||||
del libboost_python.a
|
||||
ar r libboost_python.a $(OBJ)
|
||||
|
||||
DLLWRAPOPTS=-s --driver-name g++ -s \
|
||||
--entry _DllMainCRTStartup@12 --target=i386-mingw32
|
||||
|
||||
boost_python_test.pyd: $(OBJ) comprehensive.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname boost_python_test.pyd \
|
||||
--def boost_python_test.def \
|
||||
$(OBJ) comprehensive.o $(PYLIB)
|
||||
|
||||
abstract.pyd: $(OBJ) abstract.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname abstract.pyd \
|
||||
--def abstract.def \
|
||||
$(OBJ) abstract.o $(PYLIB)
|
||||
|
||||
getting_started1.pyd: $(OBJ) getting_started1.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname getting_started1.pyd \
|
||||
--def getting_started1.def \
|
||||
$(OBJ) getting_started1.o $(PYLIB)
|
||||
|
||||
getting_started2.pyd: $(OBJ) getting_started2.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname getting_started2.pyd \
|
||||
--def getting_started2.def \
|
||||
$(OBJ) getting_started2.o $(PYLIB)
|
||||
|
||||
simple_vector.pyd: $(OBJ) simple_vector.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname simple_vector.pyd \
|
||||
--def simple_vector.def \
|
||||
$(OBJ) simple_vector.o $(PYLIB)
|
||||
|
||||
do_it_yourself_converters.pyd: $(OBJ) do_it_yourself_converters.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname do_it_yourself_converters.pyd \
|
||||
--def do_it_yourself_converters.def \
|
||||
$(OBJ) do_it_yourself_converters.o $(PYLIB)
|
||||
|
||||
pickle1.pyd: $(OBJ) pickle1.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname pickle1.pyd \
|
||||
--def pickle1.def \
|
||||
$(OBJ) pickle1.o $(PYLIB)
|
||||
|
||||
pickle2.pyd: $(OBJ) pickle2.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname pickle2.pyd \
|
||||
--def pickle2.def \
|
||||
$(OBJ) pickle2.o $(PYLIB)
|
||||
|
||||
pickle3.pyd: $(OBJ) pickle3.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname pickle3.pyd \
|
||||
--def pickle3.def \
|
||||
$(OBJ) pickle3.o $(PYLIB)
|
||||
|
||||
noncopyable_export.pyd: $(OBJ) noncopyable_export.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname noncopyable_export.pyd \
|
||||
--def noncopyable_export.def \
|
||||
$(OBJ) noncopyable_export.o $(PYLIB)
|
||||
|
||||
noncopyable_import.pyd: $(OBJ) noncopyable_import.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname noncopyable_import.pyd \
|
||||
--def noncopyable_import.def \
|
||||
$(OBJ) noncopyable_import.o $(PYLIB)
|
||||
|
||||
ivect.pyd: $(OBJ) ivect.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname ivect.pyd \
|
||||
--def ivect.def \
|
||||
$(OBJ) ivect.o $(PYLIB)
|
||||
|
||||
dvect.pyd: $(OBJ) dvect.o
|
||||
dllwrap $(DLLWRAPOPTS) \
|
||||
--dllname dvect.pyd \
|
||||
--def dvect.def \
|
||||
$(OBJ) dvect.o $(PYLIB)
|
||||
|
||||
.cpp.o:
|
||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||
|
||||
test:
|
||||
# $(PYEXE) comprehensive.py
|
||||
$(PYEXE) test_abstract.py
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_converters.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py
|
||||
|
||||
clean:
|
||||
del *.o
|
||||
del *.a
|
||||
del *.pyd
|
||||
del *.pyc
|
||||
|
||||
softlinks:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks
|
||||
|
||||
unlink:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink
|
||||
|
||||
cp:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp
|
||||
|
||||
rm:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm
|
||||
|
||||
copy:
|
||||
$(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy
|
||||
|
||||
del:
|
||||
$(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del
|
||||
BIN
build/python_v1.zip
Normal file
@@ -1,135 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="rwgk1" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=rwgk1 - Win32 DebugPython
|
||||
!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 "rwgk1.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 "rwgk1.mak" CFG="rwgk1 - Win32 DebugPython"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "rwgk1 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "rwgk1 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "rwgk1 - Win32 DebugPython" (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)" == "rwgk1 - 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 "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /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 gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "rwgk1 - 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 "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /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 gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "rwgk1 - Win32 DebugPython"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "rwgk1___Win32_DebugPython"
|
||||
# PROP BASE Intermediate_Dir "rwgk1___Win32_DebugPython"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "DebugPython"
|
||||
# PROP Intermediate_Dir "DebugPython"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RWGK1_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /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 /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
# ADD 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 /incremental:no /debug /machine:I386 /out:"DebugPython/rwgk1_d.dll" /pdbtype:sept /libpath:"C:\tools\python\src\PCbuild"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "rwgk1 - Win32 Release"
|
||||
# Name "rwgk1 - Win32 Debug"
|
||||
# Name "rwgk1 - Win32 DebugPython"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\example\rwgk1.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# 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
|
||||
@@ -1,145 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="test" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=test - Win32 DebugPython
|
||||
!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 "test.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 "test.mak" CFG="test - Win32 DebugPython"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "test - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "test - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "test - Win32 DebugPython" (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)" == "test - 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 "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /Zm200 /c
|
||||
# SUBTRACT CPP /Fr
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /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 gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/boost_python_test.dll" /libpath:"c:\tools\python\libs"
|
||||
|
||||
!ELSEIF "$(CFG)" == "test - 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 "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c
|
||||
# SUBTRACT CPP /Fr
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /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 gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"Debug/boost_python_test.dll" /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "test - Win32 DebugPython"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "test___Win32_DebugPython"
|
||||
# PROP BASE Intermediate_Dir "test___Win32_DebugPython"
|
||||
# PROP BASE Ignore_Export_Lib 0
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "DebugPython"
|
||||
# PROP Intermediate_Dir "DebugPython"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /YX /FD /GZ /Zm200 /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm- /GR /GX /Zi /Od /I "..\..\..\.." /I "c:\tools\python\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEST_EXPORTS" /D "BOOST_DEBUG_PYTHON" /YX /FD /GZ /Zm200 /EHs /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /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 /incremental:no /debug /machine:I386 /pdbtype:sept /libpath:"c:\tools\python\libs"
|
||||
# SUBTRACT BASE LINK32 /pdb:none
|
||||
# ADD 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 /incremental:no /debug /machine:I386 /out:"DebugPython/boost_python_test_d.dll" /pdbtype:sept /libpath:"c:\tools\python\src\PCbuild"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "test - Win32 Release"
|
||||
# Name "test - Win32 Debug"
|
||||
# Name "test - Win32 DebugPython"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\test\comprehensive.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\test\comprehensive.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
|
||||
@@ -1,175 +0,0 @@
|
||||
# Usage:
|
||||
#
|
||||
# Create a new empty directory anywhere (preferably not in the boost tree).
|
||||
# Copy this Makefile to that new directory and rename it to "Makefile"
|
||||
# Adjust the pathnames below.
|
||||
#
|
||||
# make softlinks Create softlinks to source code and tests
|
||||
# make Compile all sources
|
||||
# make test Run doctest tests
|
||||
# make clean Remove all object files
|
||||
# make unlink Remove softlinks
|
||||
#
|
||||
# Revision history:
|
||||
# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve)
|
||||
# Initial version: R.W. Grosse-Kunstleve
|
||||
|
||||
ROOT=$(HOME)
|
||||
BOOST=$(ROOT)/boost
|
||||
|
||||
PYEXE=/usr/local/Python-1.5.2/bin/python
|
||||
PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||
#PYEXE=/usr/local/Python-2.0/bin/python
|
||||
#PYINC=-I/usr/local/Python-2.0/include/python2.0
|
||||
#STLPORTINC=-I/usr/local/STLport-4.1b3/stlport
|
||||
#STLPORTINC=-I/usr/local/STLport-4.1b4/stlport
|
||||
#STLPORTOPTS= \
|
||||
# -D__USE_STD_IOSTREAM \
|
||||
# -D__STL_NO_SGI_IOSTREAMS \
|
||||
# -D__STL_USE_NATIVE_STRING \
|
||||
# -D__STL_NO_NEW_C_HEADERS \
|
||||
# -D_RWSTD_COMPILE_INSTANTIATE=1
|
||||
STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers
|
||||
|
||||
STDOPTS=-std strict_ansi
|
||||
# use -msg_display_number to obtain integer tags for -msg_disable
|
||||
WARNOPTS=-msg_disable 186,450,1115
|
||||
OPTOPTS=-g
|
||||
|
||||
CPP=cxx
|
||||
CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) -I$(BOOST) $(PYINC) \
|
||||
$(STDOPTS) $(WARNOPTS) $(OPTOPTS)
|
||||
MAKEDEP=-Em
|
||||
|
||||
LD=cxx
|
||||
LDOPTS=-shared -expect_unresolved 'Py*' -expect_unresolved '_Py*'
|
||||
|
||||
#HIDDEN=-hidden
|
||||
|
||||
OBJ=classes.o conversions.o extension_class.o functions.o \
|
||||
init_function.o module_builder.o \
|
||||
objects.o types.o cross_module.o
|
||||
DEPOBJ=$(OBJ) \
|
||||
comprehensive.o \
|
||||
abstract.o \
|
||||
getting_started1.o getting_started2.o \
|
||||
simple_vector.o \
|
||||
do_it_yourself_converters.o \
|
||||
pickle1.o pickle2.o pickle3.o \
|
||||
noncopyable_export.o noncopyable_import.o \
|
||||
ivect.o dvect.o
|
||||
|
||||
.SUFFIXES: .o .cpp
|
||||
|
||||
all: libboost_python.a \
|
||||
boost_python_test.so \
|
||||
abstract.so \
|
||||
getting_started1.so getting_started2.so \
|
||||
simple_vector.so \
|
||||
do_it_yourself_converters.so \
|
||||
pickle1.so pickle2.so pickle3.so \
|
||||
noncopyable_export.so noncopyable_import.so \
|
||||
ivect.so dvect.so
|
||||
|
||||
libboost_python.a: $(OBJ)
|
||||
rm -f libboost_python.a
|
||||
cd cxx_repository; \
|
||||
ls -1 > ../libboost_python.a.input; \
|
||||
ar r ../libboost_python.a -input ../libboost_python.a.input
|
||||
rm -f libboost_python.a.input
|
||||
ar r libboost_python.a $(OBJ)
|
||||
|
||||
boost_python_test.so: $(OBJ) comprehensive.o
|
||||
$(LD) $(LDOPTS) $(OBJ) comprehensive.o -o boost_python_test.so -lm
|
||||
|
||||
abstract.so: $(OBJ) abstract.o
|
||||
$(LD) $(LDOPTS) $(OBJ) abstract.o -o abstract.so
|
||||
|
||||
getting_started1.so: $(OBJ) getting_started1.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started1.o -o getting_started1.so
|
||||
|
||||
getting_started2.so: $(OBJ) getting_started2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started2.o -o getting_started2.so
|
||||
|
||||
simple_vector.so: $(OBJ) simple_vector.o
|
||||
$(LD) $(LDOPTS) $(OBJ) simple_vector.o -o simple_vector.so
|
||||
|
||||
do_it_yourself_converters.so: $(OBJ) do_it_yourself_converters.o
|
||||
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.o -o do_it_yourself_converters.so
|
||||
|
||||
pickle1.so: $(OBJ) pickle1.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle1.o -o pickle1.so
|
||||
|
||||
pickle2.so: $(OBJ) pickle2.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle2.o -o pickle2.so
|
||||
|
||||
pickle3.so: $(OBJ) pickle3.o
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle3.o -o pickle3.so
|
||||
|
||||
noncopyable_export.so: $(OBJ) noncopyable_export.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \
|
||||
noncopyable_export.o -o noncopyable_export.so
|
||||
|
||||
noncopyable_import.so: $(OBJ) noncopyable_import.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) \
|
||||
noncopyable_import.o -o noncopyable_import.so
|
||||
|
||||
ivect.so: $(OBJ) ivect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) ivect.o -o ivect.so
|
||||
|
||||
dvect.so: $(OBJ) dvect.o
|
||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
||||
|
||||
.cpp.o:
|
||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||
|
||||
test:
|
||||
$(PYEXE) comprehensive.py
|
||||
$(PYEXE) test_abstract.py
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_converters.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
||||
rm -f comprehensive.o boost_python_test.so
|
||||
rm -f abstract.o abstract.so
|
||||
rm -f getting_started1.o getting_started1.so
|
||||
rm -f getting_started2.o getting_started2.so
|
||||
rm -f simple_vector.o simple_vector.so
|
||||
rm -f do_it_yourself_converters.o do_it_yourself_converters.so
|
||||
rm -f pickle1.o pickle1.so
|
||||
rm -f pickle2.o pickle2.so
|
||||
rm -f pickle3.o pickle3.so
|
||||
rm -f noncopyable_export.o noncopyable_export.so
|
||||
rm -f noncopyable_import.o noncopyable_import.so
|
||||
rm -f ivect.o ivect.so
|
||||
rm -f dvect.o dvect.so
|
||||
rm -f so_locations *.pyc
|
||||
rm -rf cxx_repository
|
||||
|
||||
softlinks:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) softlinks
|
||||
|
||||
unlink:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) unlink
|
||||
|
||||
cp:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) cp
|
||||
|
||||
rm:
|
||||
$(PYEXE) $(BOOST)/libs/python/build/filemgr.py $(BOOST) rm
|
||||
|
||||
depend:
|
||||
@ cat Makefile.nodepend; \
|
||||
for obj in $(DEPOBJ); \
|
||||
do \
|
||||
bn=`echo "$$obj" | cut -d. -f1`; \
|
||||
$(CPP) $(CPPOPTS) $(MAKEDEP) "$$bn".cpp; \
|
||||
done
|
||||
|
||||
129
build/vc60.mak
@@ -1,129 +0,0 @@
|
||||
# Usage:
|
||||
#
|
||||
# make copy Copy the sources and tests
|
||||
# make Compile all sources
|
||||
# make test Run doctest tests
|
||||
# make clean Remove all object files
|
||||
# make del Remove the sources and tests
|
||||
#
|
||||
# Revision history:
|
||||
# 12 Apr 01 new macro ROOT to simplify configuration (R.W. Grosse-Kunstleve)
|
||||
# Initial version: R.W. Grosse-Kunstleve
|
||||
|
||||
ROOT=L:
|
||||
BOOST_WIN="$(ROOT)\boost"
|
||||
BOOST_UNIX=$(HOME)/boost
|
||||
|
||||
PYEXE="C:\Program files\Python\python.exe"
|
||||
PYINC=/I"C:\Program files\Python\include"
|
||||
PYLIB="C:\Program files\Python\libs\python15.lib"
|
||||
|
||||
STDOPTS=/nologo /MD /GR /GX /Zm200
|
||||
WARNOPTS=
|
||||
OPTOPTS=
|
||||
|
||||
CPP=cl.exe
|
||||
CPPOPTS=$(STLPORTINC) $(STLPORTOPTS) /I$(BOOST_WIN) $(PYINC) \
|
||||
$(STDOPTS) $(WARNOPTS) $(OPTOPTS)
|
||||
|
||||
LD=link.exe
|
||||
LDOPTS=/nologo /dll /incremental:no
|
||||
|
||||
OBJ=classes.obj conversions.obj extension_class.obj functions.obj \
|
||||
init_function.obj module_builder.obj \
|
||||
objects.obj types.obj cross_module.obj
|
||||
|
||||
.SUFFIXES: .obj .cpp
|
||||
|
||||
all: boost_python.lib \
|
||||
boost_python_test.pyd \
|
||||
abstract.pyd \
|
||||
getting_started1.pyd getting_started2.pyd \
|
||||
simple_vector.pyd \
|
||||
do_it_yourself_converters.pyd \
|
||||
pickle1.pyd pickle2.pyd pickle3.pyd \
|
||||
noncopyable_export.pyd noncopyable_import.pyd \
|
||||
ivect.pyd dvect.pyd
|
||||
|
||||
boost_python.lib: $(OBJ)
|
||||
$(LD) -lib /nologo /out:boost_python.lib $(OBJ)
|
||||
|
||||
boost_python_test.pyd: $(OBJ) comprehensive.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) comprehensive.obj $(PYLIB) /export:initboost_python_test /out:"boost_python_test.pyd"
|
||||
|
||||
abstract.pyd: $(OBJ) abstract.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) abstract.obj $(PYLIB) /export:initabstract /out:"abstract.pyd"
|
||||
|
||||
getting_started1.pyd: $(OBJ) getting_started1.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started1.obj $(PYLIB) /export:initgetting_started1 /out:"getting_started1.pyd"
|
||||
|
||||
getting_started2.pyd: $(OBJ) getting_started2.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) getting_started2.obj $(PYLIB) /export:initgetting_started2 /out:"getting_started2.pyd"
|
||||
|
||||
simple_vector.pyd: $(OBJ) simple_vector.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) simple_vector.obj $(PYLIB) /export:initsimple_vector /out:"simple_vector.pyd"
|
||||
|
||||
do_it_yourself_converters.pyd: $(OBJ) do_it_yourself_converters.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) do_it_yourself_converters.obj $(PYLIB) /export:initdo_it_yourself_converters /out:"do_it_yourself_converters.pyd"
|
||||
|
||||
pickle1.pyd: $(OBJ) pickle1.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle1.obj $(PYLIB) /export:initpickle1 /out:"pickle1.pyd"
|
||||
|
||||
pickle2.pyd: $(OBJ) pickle2.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle2.obj $(PYLIB) /export:initpickle2 /out:"pickle2.pyd"
|
||||
|
||||
pickle3.pyd: $(OBJ) pickle3.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) pickle3.obj $(PYLIB) /export:initpickle3 /out:"pickle3.pyd"
|
||||
|
||||
noncopyable_export.pyd: $(OBJ) noncopyable_export.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) noncopyable_export.obj $(PYLIB) /export:initnoncopyable_export /out:"noncopyable_export.pyd"
|
||||
|
||||
noncopyable_import.pyd: $(OBJ) noncopyable_import.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) noncopyable_import.obj $(PYLIB) /export:initnoncopyable_import /out:"noncopyable_import.pyd"
|
||||
|
||||
ivect.pyd: $(OBJ) ivect.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) ivect.obj $(PYLIB) /export:initivect /out:"ivect.pyd"
|
||||
|
||||
dvect.pyd: $(OBJ) dvect.obj
|
||||
$(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) /export:initdvect /out:"dvect.pyd"
|
||||
|
||||
.cpp.obj:
|
||||
$(CPP) $(CPPOPTS) /c $*.cpp
|
||||
|
||||
test:
|
||||
$(PYEXE) comprehensive.py --broken-auto-ptr
|
||||
$(PYEXE) test_abstract.py
|
||||
$(PYEXE) test_getting_started1.py
|
||||
$(PYEXE) test_getting_started2.py
|
||||
$(PYEXE) test_simple_vector.py
|
||||
$(PYEXE) test_do_it_yourself_converters.py
|
||||
$(PYEXE) test_pickle1.py
|
||||
$(PYEXE) test_pickle2.py
|
||||
$(PYEXE) test_pickle3.py
|
||||
$(PYEXE) test_cross_module.py --broken-auto-ptr
|
||||
|
||||
clean:
|
||||
del *.obj
|
||||
del *.lib
|
||||
del *.exp
|
||||
del *.idb
|
||||
del *.pyd
|
||||
del *.pyc
|
||||
|
||||
softlinks:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks
|
||||
|
||||
unlink:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) unlink
|
||||
|
||||
cp:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) cp
|
||||
|
||||
rm:
|
||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) rm
|
||||
|
||||
copy:
|
||||
$(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) copy
|
||||
|
||||
del:
|
||||
$(PYEXE) $(BOOST_WIN)\libs\python\build\filemgr.py $(BOOST_WIN) del
|
||||
23
doc/Jamfile
Normal file
@@ -0,0 +1,23 @@
|
||||
# Copyright David Abrahams 2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
import docutils ;
|
||||
|
||||
import path ;
|
||||
sources = building.rst ;
|
||||
bases = $(sources:S=) ;
|
||||
|
||||
# This is a path relative to the html/ subdirectory where the
|
||||
# generated output will eventually be moved.
|
||||
stylesheet = "--stylesheet=../../../rst.css" ;
|
||||
|
||||
for local b in $(bases)
|
||||
{
|
||||
html $(b) : $(b).rst :
|
||||
|
||||
<docutils-html>"-gdt --source-url="./$(b).rst" --link-stylesheet --traceback --trim-footnote-reference-space --footnote-references=superscript "$(stylesheet)
|
||||
;
|
||||
}
|
||||
|
||||
alias htmls : $(bases) ;
|
||||
stage . : $(bases) ;
|
||||
22
doc/PyConDC_2003/bpl.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
|
||||
<meta http-equiv="refresh" content="0; URL=http://www.boost-consulting.com/writing/bpl.html">
|
||||
|
||||
<title>Loading: “Building Hybrid Systems With Boost.Python”</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
Loading...; if nothing happens, please go to <a href= "http://www.boost-consulting.com/writing/bpl.html">http://www.boost-consulting.com/writing/bpl.html</a>.
|
||||
</body>
|
||||
</html>
|
||||
|
||||
BIN
doc/PyConDC_2003/bpl.pdf
Normal file
5
doc/PyConDC_2003/bpl.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
.. Copyright David Abrahams 2006. Distributed under the Boost
|
||||
.. Software License, Version 1.0. (See accompanying
|
||||
.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
This file has been moved to http://www.boost-consulting.com/writing/bpl.txt.
|
||||
912
doc/PyConDC_2003/bpl_mods.txt
Normal file
@@ -0,0 +1,912 @@
|
||||
Copyright David Abrahams 2006. Distributed under the Boost
|
||||
Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
.. 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
|
||||
necessary 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
|
||||
necessary 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 necessary 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
|
||||
190
doc/PyConDC_2003/default.css
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
:Author: David Goodger
|
||||
:Contact: goodger@users.sourceforge.net
|
||||
:date: $Date$
|
||||
:version: $Revision$
|
||||
:copyright: This stylesheet has been placed in the public domain.
|
||||
|
||||
boostinspect:nolicense
|
||||
|
||||
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 }
|
||||
BIN
doc/PyConDC_2003/python_cpp_mix.jpg
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
doc/PyConDC_2003/python_cpp_mix.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
63
doc/boost.css
Normal file
@@ -0,0 +1,63 @@
|
||||
/* Copyright David Abrahams 2006. Distributed under the Boost
|
||||
Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
H1
|
||||
{
|
||||
FONT-SIZE: 200%
|
||||
COLOR: #00007f
|
||||
}
|
||||
H2
|
||||
{
|
||||
FONT-SIZE: 150%;
|
||||
}
|
||||
H3
|
||||
{
|
||||
FONT-SIZE: 125%;
|
||||
}
|
||||
H4
|
||||
{
|
||||
FONT-SIZE: 108%;
|
||||
}
|
||||
BODY
|
||||
{
|
||||
FONT-SIZE: 100%;
|
||||
BACKGROUND-COLOR: #ffffff
|
||||
}
|
||||
PRE
|
||||
{
|
||||
MARGIN-LEFT: 2pc;
|
||||
FONT-SIZE: 80%;
|
||||
BACKGROUND-COLOR: #dfffff
|
||||
}
|
||||
CODE
|
||||
{
|
||||
FONT-SIZE: 95%;
|
||||
white-space: pre
|
||||
}
|
||||
.index
|
||||
{
|
||||
TEXT-ALIGN: left
|
||||
}
|
||||
.page-index
|
||||
{
|
||||
TEXT-ALIGN: left
|
||||
}
|
||||
.definition
|
||||
{
|
||||
TEXT-ALIGN: left
|
||||
}
|
||||
.footnote
|
||||
{
|
||||
FONT-SIZE: 66%;
|
||||
VERTICAL-ALIGN: super;
|
||||
TEXT-DECORATION: none
|
||||
}
|
||||
.function-semantics
|
||||
{
|
||||
CLEAR: left
|
||||
}
|
||||
.metafunction-semantics
|
||||
{
|
||||
CLEAR: left
|
||||
}
|
||||
@@ -1,180 +1,636 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<?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.5: http://docutils.sourceforge.net/" />
|
||||
<title>Boost C++ Libraries: Boost.Python Build and Test HOWTO</title>
|
||||
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document" id="logo-boost-python-build-and-test-howto">
|
||||
<h1 class="title"><a class="reference external" href="../index.html"><img alt="Boost C++ Libraries:" class="boost-logo" src="../../../boost.png" /></a> Boost.Python Build and Test HOWTO</h1>
|
||||
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at -->
|
||||
<!-- http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<div class="contents sidebar small topic" id="contents">
|
||||
<p class="topic-title first">Contents</p>
|
||||
<ul class="auto-toc simple">
|
||||
<li><a class="reference internal" href="#requirements" id="id25">1 Requirements</a></li>
|
||||
<li><a class="reference internal" href="#background" id="id26">2 Background</a></li>
|
||||
<li><a class="reference internal" href="#no-install-quickstart" id="id27">3 No-Install Quickstart</a><ul class="auto-toc">
|
||||
<li><a class="reference internal" href="#basic-procedure" id="id28">3.1 Basic Procedure</a></li>
|
||||
<li><a class="reference internal" href="#in-case-of-trouble" id="id29">3.2 In Case of Trouble</a></li>
|
||||
<li><a class="reference internal" href="#in-case-everything-seemed-to-work" id="id30">3.3 In Case Everything Seemed to Work</a></li>
|
||||
<li><a class="reference internal" href="#modifying-the-example-project" id="id31">3.4 Modifying the Example Project</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#installing-boost-python-on-your-system" id="id32">4 Installing Boost.Python on your System</a></li>
|
||||
<li><a class="reference internal" href="#configuring-boost-build" id="id33">5 Configuring Boost.Build</a><ul class="auto-toc">
|
||||
<li><a class="reference internal" href="#python-configuration-parameters" id="id34">5.1 Python Configuration Parameters</a></li>
|
||||
<li><a class="reference internal" href="#examples" id="id35">5.2 Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#choosing-a-boost-python-library-binary" id="id36">6 Choosing a Boost.Python Library Binary</a><ul class="auto-toc">
|
||||
<li><a class="reference internal" href="#the-dynamic-binary" id="id37">6.1 The Dynamic Binary</a></li>
|
||||
<li><a class="reference internal" href="#the-static-binary" id="id38">6.2 The Static Binary</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#include-issues" id="id39">7 <tt class="docutils literal"><span class="pre">#include</span></tt> Issues</a></li>
|
||||
<li><a class="reference internal" href="#python-debugging-builds" id="id40">8 Python Debugging Builds</a></li>
|
||||
<li><a class="reference internal" href="#testing-boost-python" id="id41">9 Testing Boost.Python</a></li>
|
||||
<li><a class="reference internal" href="#notes-for-mingw-and-cygwin-with-mno-cygwin-gcc-users" id="id42">10 Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="requirements">
|
||||
<h1><a class="toc-backref" href="#id25">1 Requirements</a></h1>
|
||||
<p>Boost.Python requires <a class="reference external" href="http://www.python.org/2.2">Python 2.2</a><a class="footnote-reference" href="#id22" id="id2"><sup>1</sup></a> <em>or</em> <a class="reference external" href="http://www.python.org"><em>newer</em></a>.</p>
|
||||
</div>
|
||||
<div class="section" id="background">
|
||||
<h1><a class="toc-backref" href="#id26">2 Background</a></h1>
|
||||
<p>There are two basic models for combining C++ and Python:</p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference external" href="http://www.python.org/doc/current/ext/intro.html">extending</a>, in which the end-user launches the Python interpreter
|
||||
executable and imports Python “extension modules” written in C++.
|
||||
Think of taking a library written in C++ and giving it a Python
|
||||
interface so Python programmers can use it. From Python, these
|
||||
modules look just like regular Python modules.</li>
|
||||
<li><a class="reference external" href="http://www.python.org/doc/current/ext/embedding.html">embedding</a>, in which the end-user launches a program written
|
||||
in C++ that in turn invokes the Python interpreter as a library
|
||||
subroutine. Think of adding scriptability to an existing
|
||||
application.</li>
|
||||
</ul>
|
||||
<p>The key distinction between extending and embedding is the location
|
||||
of the C++ <tt class="docutils literal"><span class="pre">main()</span></tt> function: in the Python interpreter executable,
|
||||
or in some other program, respectively. Note that even when
|
||||
embedding Python in another program, <a class="reference external" href="http://www.python.org/doc/current/ext/extending-with-embedding.html">extension modules are often
|
||||
the best way to make C/C++ functionality accessible to Python
|
||||
code</a>, so the use of extension modules is really at the heart of
|
||||
both models.</p>
|
||||
<p>Except in rare cases, extension modules are built as
|
||||
dynamically-loaded libraries with a single entry point, which means
|
||||
you can change them without rebuilding either the other extension
|
||||
modules or the executable containing <tt class="docutils literal"><span class="pre">main()</span></tt>.</p>
|
||||
</div>
|
||||
<div class="section" id="no-install-quickstart">
|
||||
<span id="quickstart"></span><h1><a class="toc-backref" href="#id27">3 No-Install Quickstart</a></h1>
|
||||
<p>There is no need to “install Boost” in order to get started using
|
||||
Boost.Python. These instructions use <a class="reference external" href="../../../tools/build/index.html">Boost.Build</a> projects,
|
||||
which will build those binaries as soon as they're needed. Your
|
||||
first tests may take a little longer while you wait for
|
||||
Boost.Python to build, but doing things this way will save you from
|
||||
worrying about build intricacies like which library binaries to use
|
||||
for a specific compiler configuration and figuring out the right
|
||||
compiler options to use yourself.</p>
|
||||
<!-- .. raw:: html
|
||||
|
||||
<title>Building an Extension Module</title>
|
||||
<div style="width:50%"> -->
|
||||
<div class="note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p>Of course it's possible to use other build systems to
|
||||
build Boost.Python and its extensions, but they are not
|
||||
officially supported by Boost. Moreover <strong>99% of all “I can't
|
||||
build Boost.Python” problems come from trying to use another
|
||||
build system</strong> without first following these instructions.</p>
|
||||
<p>If you want to use another system anyway, we suggest that you
|
||||
follow these instructions, and then invoke <tt class="docutils literal"><span class="pre">bjam</span></tt> with the</p>
|
||||
<pre class="literal-block">
|
||||
<tt class="docutils literal"><span class="pre">-a</span> <span class="pre">-o</span></tt><em>filename</em>
|
||||
</pre>
|
||||
<p class="last">options to dump the build commands it executes to a file, so
|
||||
you can see what your alternate build system needs to do.</p>
|
||||
</div>
|
||||
<!-- .. raw:: html
|
||||
|
||||
<div>
|
||||
<h1><img width="277" height="86" align="center" src=
|
||||
"../../../c++boost.gif" alt="c++boost.gif (8819 bytes)">Building an
|
||||
Extension Module</h1>
|
||||
</div> -->
|
||||
<div class="section" id="basic-procedure">
|
||||
<h2><a class="toc-backref" href="#id28">3.1 Basic Procedure</a></h2>
|
||||
<ol class="arabic">
|
||||
<li><p class="first">Get Boost; see sections 1 and 2 [<a class="reference external" href="../../../more/getting_started/unix-variants.html#get-boost">Unix/Linux</a>, <a class="reference external" href="../../../more/getting_started/windows.html#get-boost">Windows</a>] of the
|
||||
Boost <a class="reference external" href="../../../more/getting_started/index.html">Getting Started Guide</a>.</p>
|
||||
</li>
|
||||
<li><p class="first">Get the <tt class="docutils literal"><span class="pre">bjam</span></tt> build driver. See section 5 [<a class="reference external" href="../../../more/getting_started/unix-variants.html#prepare-to-use-a-boost-library-binary">Unix/Linux</a>,
|
||||
<a class="reference external" href="../../../more/getting_started/windows.html#prepare-to-use-a-boost-library-binary">Windows</a>] of the Boost <a class="reference external" href="../../../more/getting_started/index.html">Getting Started Guide</a>.</p>
|
||||
</li>
|
||||
<li><p class="first">cd into the <tt class="docutils literal"><span class="pre">libs/python/example/quickstart/</span></tt> directory of your
|
||||
Boost installation, which contains a small example project.</p>
|
||||
</li>
|
||||
<li><p class="first">Invoke <tt class="docutils literal"><span class="pre">bjam</span></tt>. Replace the “<tt class="docutils literal"><span class="pre">stage</span></tt>“ argument from the
|
||||
example invocation from section 5 of the <a class="reference external" href="../../../more/getting_started/index.html">Getting Started
|
||||
Guide</a> with “<tt class="docutils literal"><span class="pre">test</span></tt>,“ to build all the test targets. Also add
|
||||
the argument “<tt class="docutils literal"><span class="pre">--verbose-test</span></tt>” to see the output generated by
|
||||
the tests when they are run.</p>
|
||||
<p>On Windows, your <tt class="docutils literal"><span class="pre">bjam</span></tt> invocation might look something like:</p>
|
||||
<pre class="literal-block">
|
||||
C:\boost_1_34_0\…\quickstart> <strong>bjam toolset=msvc --verbose-test test</strong>
|
||||
</pre>
|
||||
<p>and on Unix variants, perhaps,</p>
|
||||
<pre class="literal-block">
|
||||
~/boost_1_34_0/…/quickstart$ <strong>bjam toolset=gcc --verbose-test test</strong>
|
||||
</pre>
|
||||
</li>
|
||||
</ol>
|
||||
<div class="admonition-note-to-windows-users admonition">
|
||||
<p class="first admonition-title">Note to Windows Users</p>
|
||||
<p class="last">For the sake of concision, the rest of this guide will use
|
||||
unix-style forward slashes in pathnames instead of the
|
||||
backslashes with which you may be more familiar. The forward
|
||||
slashes should work everywhere except in <a class="reference external" href="../../../more/getting_started/windows.html#command-prompt">Command Prompt</a>
|
||||
windows, where you should use backslashes.</p>
|
||||
</div>
|
||||
<p>If you followed this procedure successfully, you will have built an
|
||||
extension module called <tt class="docutils literal"><span class="pre">extending</span></tt> and tested it by running a
|
||||
Python script called <tt class="docutils literal"><span class="pre">test_extending.py</span></tt>. You will also have
|
||||
built and run a simple application called <tt class="docutils literal"><span class="pre">embedding</span></tt> that embeds
|
||||
python.</p>
|
||||
</div>
|
||||
<div class="section" id="in-case-of-trouble">
|
||||
<h2><a class="toc-backref" href="#id29">3.2 In Case of Trouble</a></h2>
|
||||
<p>If you're seeing lots of compiler and/or linker error messages,
|
||||
it's probably because Boost.Build is having trouble finding your
|
||||
Python installation. You might want to pass the
|
||||
<tt class="docutils literal"><span class="pre">--debug-configuration</span></tt> option to <tt class="docutils literal"><span class="pre">bjam</span></tt> the first few times
|
||||
you invoke it, to make sure that Boost.Build is correctly locating
|
||||
all the parts of your Python installation. If it isn't, consider
|
||||
<a class="reference internal" href="#configuring-boost-build">Configuring Boost.Build</a> as detailed below.</p>
|
||||
<p>If you're still having trouble, Someone on one of the following
|
||||
mailing lists may be able to help:</p>
|
||||
<ul class="simple">
|
||||
<li>The <a class="reference external" href="http://www.boost.org/more/mailing_lists.htm#jamboost">Boost.Build mailing list</a> for issues related to Boost.Build</li>
|
||||
<li>The Python <a class="reference external" href="http://www.boost.org/more/mailing_lists.htm#cplussig">C++ Sig</a> for issues specifically related to Boost.Python</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="in-case-everything-seemed-to-work">
|
||||
<h2><a class="toc-backref" href="#id30">3.3 In Case Everything Seemed to Work</a></h2>
|
||||
<p>Rejoice! If you're new to Boost.Python, at this point it might be
|
||||
a good idea to ignore build issues for a while and concentrate on
|
||||
learning the library by going through the <a class="reference external" href="tutorial/index.html">tutorial</a> and perhaps
|
||||
some of the <a class="reference external" href="v2/reference.html">reference documentation</a>, trying out what you've
|
||||
learned about the API by modifying the quickstart project.</p>
|
||||
</div>
|
||||
<div class="section" id="modifying-the-example-project">
|
||||
<h2><a class="toc-backref" href="#id31">3.4 Modifying the Example Project</a></h2>
|
||||
<p>If you're content to keep your extension module forever in one
|
||||
source file called <a class="reference external" href="../example/quickstart/extending.cpp"><tt class="docutils literal"><span class="pre">extending.cpp</span></tt></a>, inside your Boost
|
||||
distribution, and import it forever as <tt class="docutils literal"><span class="pre">extending</span></tt>, then you can
|
||||
stop here. However, it's likely that you will want to make a few
|
||||
changes. There are a few things you can do without having to learn
|
||||
<a class="reference external" href="../../../tools/build/index.html">Boost.Build</a> in depth.</p>
|
||||
<p>The project you just built is specified in two files in the current
|
||||
directory: <a class="reference external" href="../example/quickstart/boost-build.jam"><tt class="docutils literal"><span class="pre">boost-build.jam</span></tt></a>, which tells <tt class="docutils literal"><span class="pre">bjam</span></tt> where it can
|
||||
find the interpreted code of the Boost build system, and
|
||||
<a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a>, which describes the targets you just built. These
|
||||
files are heavily commented, so they should be easy to modify.
|
||||
Take care, however, to preserve whitespace. Punctuation such as
|
||||
<tt class="docutils literal"><span class="pre">;</span></tt> will not be recognized as intended by <tt class="docutils literal"><span class="pre">bjam</span></tt> if it is not
|
||||
surrounded by whitespace.</p>
|
||||
<div class="section" id="relocate-the-project">
|
||||
<h3>Relocate the Project</h3>
|
||||
<p>You'll probably want to copy this project elsewhere so you can
|
||||
change it without modifying your Boost distribution. To do that,
|
||||
simply</p>
|
||||
<ol class="loweralpha simple">
|
||||
<li>copy the entire <tt class="docutils literal"><span class="pre">libs/python/example/quickstart/</span></tt> directory
|
||||
into a new directory.</li>
|
||||
<li>In the new copies of <a class="reference external" href="../example/quickstart/boost-build.jam"><tt class="docutils literal"><span class="pre">boost-build.jam</span></tt></a> and <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a>, locate
|
||||
the relative path near the top of the file that is clearly
|
||||
marked by a comment, and edit that path so that it refers to the
|
||||
same directory your Boost distribution as it referred to when
|
||||
the file was in its original location in the
|
||||
<tt class="docutils literal"><span class="pre">libs/python/example/quickstart/</span></tt> directory.</li>
|
||||
</ol>
|
||||
<p>For example, if you moved the project from
|
||||
<tt class="docutils literal"><span class="pre">/home/dave/boost_1_34_0/libs/python/example/quickstart</span></tt> to
|
||||
<tt class="docutils literal"><span class="pre">/home/dave/my-project</span></tt>, you could change the first path in
|
||||
<a class="reference external" href="../example/quickstart/boost-build.jam"><tt class="docutils literal"><span class="pre">boost-build.jam</span></tt></a> from</p>
|
||||
<pre class="literal-block">
|
||||
<strong>../../../..</strong>/tools/build/v2
|
||||
</pre>
|
||||
<p>to</p>
|
||||
<pre class="literal-block">
|
||||
<strong>/home/dave/boost_1_34_0</strong>/tools/build/v2
|
||||
</pre>
|
||||
<p>and change the first path in <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a> from</p>
|
||||
<pre class="literal-block">
|
||||
<strong>../../../..</strong>
|
||||
</pre>
|
||||
<p>to</p>
|
||||
<pre class="literal-block">
|
||||
<strong>/home/dave/boost_1_34_0</strong>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="add-new-or-change-names-of-existing-source-files">
|
||||
<h3>Add New or Change Names of Existing Source Files</h3>
|
||||
<p>The names of additional source files involved in building your
|
||||
extension module or embedding application can be listed in
|
||||
<a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a> right alongside <tt class="docutils literal"><span class="pre">extending.cpp</span></tt> or <tt class="docutils literal"><span class="pre">embedding.cpp</span></tt>
|
||||
respectively. Just be sure to leave whitespace around each
|
||||
filename:</p>
|
||||
<pre class="literal-block">
|
||||
… file1.cpp file2.cpp file3.cpp …
|
||||
</pre>
|
||||
<p>Naturally, if you want to change the name of a source file you can
|
||||
tell Boost.Build about it by editing the name in <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a>.</p>
|
||||
</div>
|
||||
<div class="section" id="change-the-name-of-your-extension-module">
|
||||
<h3>Change the Name of your Extension Module</h3>
|
||||
<p>The name of the extension module is determined by two things:</p>
|
||||
<ol class="arabic simple">
|
||||
<li>the name in <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a> immediately following <tt class="docutils literal"><span class="pre">python-extension</span></tt>, and</li>
|
||||
<li>the name passed to <tt class="docutils literal"><span class="pre">BOOST_PYTHON_MODULE</span></tt> in <a class="reference external" href="../example/quickstart/extending.cpp"><tt class="docutils literal"><span class="pre">extending.cpp</span></tt></a>.</li>
|
||||
</ol>
|
||||
<p>To change the name of the extension module from <tt class="docutils literal"><span class="pre">extending</span></tt> to
|
||||
<tt class="docutils literal"><span class="pre">hello</span></tt>, you'd edit <a class="reference external" href="../example/quickstart/Jamroot"><tt class="docutils literal"><span class="pre">Jamroot</span></tt></a>, changing</p>
|
||||
<pre class="literal-block">
|
||||
python-extension <strong>extending</strong> : extending.cpp ;
|
||||
</pre>
|
||||
<p>to</p>
|
||||
<pre class="literal-block">
|
||||
python-extension <strong>hello</strong> : extending.cpp ;
|
||||
</pre>
|
||||
<p>and you'd edit extending.cpp, changing</p>
|
||||
<pre class="literal-block">
|
||||
BOOST_PYTHON_MODULE(<strong>extending</strong>)
|
||||
</pre>
|
||||
<p>to</p>
|
||||
<pre class="literal-block">
|
||||
BOOST_PYTHON_MODULE(<strong>hello</strong>)
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="installing-boost-python-on-your-system">
|
||||
<h1><a class="toc-backref" href="#id32">4 Installing Boost.Python on your System</a></h1>
|
||||
<p>Since Boost.Python is a separately-compiled (as opposed to
|
||||
<a class="reference external" href="../../../more/getting_started/windows.html#header-only-libraries">header-only</a>) library, its user relies on the services of a
|
||||
Boost.Python library binary.</p>
|
||||
<p>If you need a regular installation of the Boost.Python library
|
||||
binaries on your system, the Boost <a class="reference external" href="../../../more/getting_started/index.html">Getting Started Guide</a> will
|
||||
walk you through the steps of creating one. If building binaries
|
||||
from source, you might want to supply the <tt class="docutils literal"><span class="pre">--with-python</span></tt>
|
||||
argument to <tt class="docutils literal"><span class="pre">bjam</span></tt> (or the <tt class="docutils literal"><span class="pre">--with-libraries=python</span></tt> argument
|
||||
to <tt class="docutils literal"><span class="pre">configure</span></tt>), so only the Boost.Python binary will be built,
|
||||
rather than all the Boost binaries.</p>
|
||||
</div>
|
||||
<div class="section" id="configuring-boost-build">
|
||||
<h1><a class="toc-backref" href="#id33">5 Configuring Boost.Build</a></h1>
|
||||
<p>As described in the <a class="reference external" href="http://www.boost.orgdoc/html/bbv2/advanced.html#bbv2.advanced.configuration">Boost.Build reference manual</a>, a file called
|
||||
<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> in your home directory<a class="footnote-reference" href="#home-dir" id="id11"><sup>6</sup></a> is used to
|
||||
specify the tools and libraries available to the build system. You
|
||||
may need to create or edit <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> to tell Boost.Build
|
||||
how to invoke Python, <tt class="docutils literal"><span class="pre">#include</span></tt> its headers, and link with its
|
||||
libraries.</p>
|
||||
<div class="admonition-users-of-unix-variant-oses admonition">
|
||||
<p class="first admonition-title">Users of Unix-Variant OSes</p>
|
||||
<p class="last">If you are using a unix-variant OS and you ran Boost's
|
||||
<tt class="docutils literal"><span class="pre">configure</span></tt> script, it may have generated a
|
||||
<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> for you.<a class="footnote-reference" href="#overwrite" id="id13"><sup>4</sup></a> If your <tt class="docutils literal"><span class="pre">configure</span></tt>/<tt class="docutils literal"><span class="pre">make</span></tt> sequence was successful and Boost.Python binaries
|
||||
were built, your <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> file is probably already
|
||||
correct.</p>
|
||||
</div>
|
||||
<p>If you have one fairly “standard” python installation for your
|
||||
platform, you might not need to do anything special to describe it. If
|
||||
you haven't configured python in <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> (and you don't
|
||||
specify <tt class="docutils literal"><span class="pre">--without-python</span></tt> on the Boost.Build command line),
|
||||
Boost.Build will automatically execute the equivalent of</p>
|
||||
<pre class="literal-block">
|
||||
import toolset : using ;
|
||||
using python ;
|
||||
</pre>
|
||||
<p>which automatically looks for Python in the most likely places.
|
||||
However, that only happens when using the Boost.Python project file
|
||||
(e.g. when referred to by another project as in the <a class="reference internal" href="#quickstart">quickstart</a>
|
||||
method). If instead you are linking against separately-compiled
|
||||
Boost.Python binaries, you should set up a <tt class="docutils literal"><span class="pre">user-config.jam</span></tt> file
|
||||
with at least the minimal incantation above.</p>
|
||||
<div class="section" id="python-configuration-parameters">
|
||||
<h2><a class="toc-backref" href="#id34">5.1 Python Configuration Parameters</a></h2>
|
||||
<p>If you have several versions of Python installed, or Python is
|
||||
installed in an unusual way, you may want to supply any or all of
|
||||
the following optional parameters to <tt class="docutils literal"><span class="pre">using</span> <span class="pre">python</span></tt>.</p>
|
||||
<dl class="docutils">
|
||||
<dt>version</dt>
|
||||
<dd>the version of Python to use. Should be in Major.Minor
|
||||
format, for example, <tt class="docutils literal"><span class="pre">2.3</span></tt>. Do not include the subminor
|
||||
version (i.e. <em>not</em> <tt class="docutils literal"><span class="pre">2.5.1</span></tt>). If you have multiple Python
|
||||
versions installed, the version will usually be the only
|
||||
configuration argument required.</dd>
|
||||
<dt>cmd-or-prefix</dt>
|
||||
<dd>preferably, a command that invokes a Python interpreter.
|
||||
Alternatively, the installation prefix for Python libraries and
|
||||
header files. Only use the alternative formulation if there is
|
||||
no appropriate Python executable available.</dd>
|
||||
<dt>includes</dt>
|
||||
<dd>the <tt class="docutils literal"><span class="pre">#include</span></tt> paths for Python headers. Normally the correct
|
||||
path(s) will be automatically deduced from <tt class="docutils literal"><span class="pre">version</span></tt> and/or
|
||||
<tt class="docutils literal"><span class="pre">cmd-or-prefix</span></tt>.</dd>
|
||||
<dt>libraries</dt>
|
||||
<dd>the path to Python library binaries. On MacOS/Darwin,
|
||||
you can also pass the path of the Python framework. Normally the
|
||||
correct path(s) will be automatically deduced from <tt class="docutils literal"><span class="pre">version</span></tt>
|
||||
and/or <tt class="docutils literal"><span class="pre">cmd-or-prefix</span></tt>.</dd>
|
||||
<dt>condition</dt>
|
||||
<dd>if specified, should be a set of Boost.Build
|
||||
properties that are matched against the build configuration when
|
||||
Boost.Build selects a Python configuration to use. See examples
|
||||
below for details.</dd>
|
||||
<dt>extension-suffix</dt>
|
||||
<dd>A string to append to the name of extension
|
||||
modules before the true filename extension. You almost certainly
|
||||
don't need to use this. Usually this suffix is only used when
|
||||
targeting a Windows debug build of Python, and will be set
|
||||
automatically for you based on the value of the
|
||||
<a class="reference internal" href="#python-debugging"><tt class="docutils literal"><span class="pre"><python-debugging></span></tt></a> feature. However, at least one Linux
|
||||
distribution (Ubuntu Feisty Fawn) has a specially configured
|
||||
<a class="reference external" href="https://wiki.ubuntu.com/PyDbgBuilds">python-dbg</a> package that claims to use such a suffix.</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="section" id="examples">
|
||||
<h2><a class="toc-backref" href="#id35">5.2 Examples</a></h2>
|
||||
<p>Note that in the examples below, case and <em>especially whitespace</em> are
|
||||
significant.</p>
|
||||
<ul>
|
||||
<li><p class="first">If you have both python 2.5 and python 2.4 installed,
|
||||
<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> might contain:</p>
|
||||
<pre class="literal-block">
|
||||
using python : 2.5 ; # Make both versions of Python available
|
||||
|
||||
<p>The build process for Boost is currently undergoing some evolution,
|
||||
and, it is to be hoped, improvement. The following facts may help:
|
||||
using python : 2.4 ; # To build with python 2.4, add python=2.4
|
||||
# to your command line.
|
||||
</pre>
|
||||
<p>The first version configured (2.5) becomes the default. To build
|
||||
against python 2.4, add <tt class="docutils literal"><span class="pre">python=2.4</span></tt> to the <tt class="docutils literal"><span class="pre">bjam</span></tt> command line.</p>
|
||||
</li>
|
||||
<li><p class="first">If you have python installed in an unusual location, you might
|
||||
supply the path to the interpreter in the <tt class="docutils literal"><span class="pre">cmd-or-prefix</span></tt>
|
||||
parameter:</p>
|
||||
<pre class="literal-block">
|
||||
using python : : /usr/local/python-2.6-beta/bin/python ;
|
||||
</pre>
|
||||
</li>
|
||||
<li><p class="first">If you have a separate build of Python for use with a particular
|
||||
toolset, you might supply that toolset in the <tt class="docutils literal"><span class="pre">condition</span></tt>
|
||||
parameter:</p>
|
||||
<pre class="literal-block">
|
||||
using python ; # use for most toolsets
|
||||
|
||||
<hr>
|
||||
Makefiles for various platforms and a Visual Studio project
|
||||
reside in the Boost subdirectory <tt>libs/python/build</tt>.
|
||||
Build targets include:
|
||||
# Use with Intel C++ toolset
|
||||
using python
|
||||
: # version
|
||||
: c:\\Devel\\Python-2.5-IntelBuild\\PCBuild\\python # cmd-or-prefix
|
||||
: # includes
|
||||
: # libraries
|
||||
: <toolset>intel # condition
|
||||
;
|
||||
</pre>
|
||||
</li>
|
||||
<li><p class="first">If you have downloaded the Python sources and built both the
|
||||
normal and the “<a class="reference internal" href="#id19">python debugging</a>” builds from source on
|
||||
Windows, you might see:</p>
|
||||
<pre class="literal-block">
|
||||
using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python ;
|
||||
using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python_d
|
||||
: # includes
|
||||
: # libs
|
||||
: <python-debugging>on ;
|
||||
</pre>
|
||||
</li>
|
||||
<li><p class="first">You can set up your user-config.jam so a bjam built under Windows
|
||||
can build/test both Windows and <a class="reference external" href="http://cygwin.com">Cygwin</a> python extensions. Just pass
|
||||
<tt class="docutils literal"><span class="pre"><target-os>cygwin</span></tt> in the <tt class="docutils literal"><span class="pre">condition</span></tt> parameter
|
||||
for the cygwin python installation:</p>
|
||||
<pre class="literal-block">
|
||||
# windows installation
|
||||
using python ;
|
||||
|
||||
<ul>
|
||||
<li>The <tt>boost_python</tt> library for static linking with your
|
||||
extension module. On the various Unices, this library will be
|
||||
called <tt>libboost_python.a</tt>. When using Visual C++, the
|
||||
library will be called <tt>boost_python.lib</tt>.
|
||||
# cygwin installation
|
||||
using python : : c:\\cygwin\\bin\\python2.5 : : : <target-os>cygwin ;
|
||||
</pre>
|
||||
<p>when you put target-os=cygwin in your build request, it should build
|
||||
with the cygwin version of python:<a class="footnote-reference" href="#flavor" id="id15"><sup>5</sup></a></p>
|
||||
<blockquote>
|
||||
<p>bjam target-os=cygwin toolset=gcc</p>
|
||||
</blockquote>
|
||||
<p>This is supposed to work the other way, too (targeting windows
|
||||
python with a <a class="reference external" href="http://cygwin.com">Cygwin</a> bjam) but it seems as though the support in
|
||||
Boost.Build's toolsets for building that way is broken at the
|
||||
time of this writing.</p>
|
||||
</li>
|
||||
<li><p class="first">Note that because of <a class="reference external" href="http://zigzag.cs.msu.su/boost.build/wiki/AlternativeSelection">the way Boost.Build currently selects target
|
||||
alternatives</a>, you might have be very explicit in your build
|
||||
requests. For example, given:</p>
|
||||
<pre class="literal-block">
|
||||
using python : 2.5 ; # a regular windows build
|
||||
using python : 2.4 : : : : <target-os>cygwin ;
|
||||
</pre>
|
||||
<p>building with</p>
|
||||
<pre class="literal-block">
|
||||
bjam target-os=cygwin
|
||||
</pre>
|
||||
<p>will yield an error. Instead, you'll need to write:</p>
|
||||
<pre class="literal-block">
|
||||
bjam target-os=cygwin/python=2.4
|
||||
</pre>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="choosing-a-boost-python-library-binary">
|
||||
<h1><a class="toc-backref" href="#id36">6 Choosing a Boost.Python Library Binary</a></h1>
|
||||
<p>If—instead of letting Boost.Build construct and link with the right
|
||||
libraries automatically—you choose to use a pre-built Boost.Python
|
||||
library, you'll need to think about which one to link with. The
|
||||
Boost.Python binary comes in both static and dynamic flavors. Take
|
||||
care to choose the right flavor for your application.<a class="footnote-reference" href="#naming" id="id17"><sup>2</sup></a></p>
|
||||
<div class="section" id="the-dynamic-binary">
|
||||
<h2><a class="toc-backref" href="#id37">6.1 The Dynamic Binary</a></h2>
|
||||
<p>The dynamic library is the safest and most-versatile choice:</p>
|
||||
<ul class="simple">
|
||||
<li>A single copy of the library code is used by all extension
|
||||
modules built with a given toolset.<a class="footnote-reference" href="#toolset-specific" id="id18"><sup>3</sup></a></li>
|
||||
<li>The library contains a type conversion registry. Because one
|
||||
registry is shared among all extension modules, instances of a
|
||||
class exposed to Python in one dynamically-loaded extension
|
||||
module can be passed to functions exposed in another such module.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="the-static-binary">
|
||||
<h2><a class="toc-backref" href="#id38">6.2 The Static Binary</a></h2>
|
||||
<p>It might be appropriate to use the static Boost.Python library in
|
||||
any of the following cases:</p>
|
||||
<ul class="simple">
|
||||
<li>You are <a class="reference external" href="http://www.python.org/doc/current/ext/intro.html">extending</a> python and the types exposed in your
|
||||
dynamically-loaded extension module don't need to be used by any
|
||||
other Boost.Python extension modules, and you don't care if the
|
||||
core library code is duplicated among them.</li>
|
||||
<li>You are <a class="reference external" href="http://www.python.org/doc/current/ext/embedding.html">embedding</a> python in your application and either:<ul>
|
||||
<li>You are targeting a Unix variant OS other than MacOS or AIX,
|
||||
where the dynamically-loaded extension modules can “see” the
|
||||
Boost.Python library symbols that are part of the executable.</li>
|
||||
<li>Or, you have statically linked some Boost.Python extension
|
||||
modules into your application and you don't care if any
|
||||
dynamically-loaded Boost.Python extension modules are able to
|
||||
use the types exposed by your statically-linked extension
|
||||
modules (and vice-versa).</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="include-issues">
|
||||
<h1><a class="toc-backref" href="#id39">7 <tt class="docutils literal"><span class="pre">#include</span></tt> Issues</a></h1>
|
||||
<ol class="arabic simple">
|
||||
<li>If you should ever have occasion to <tt class="docutils literal"><span class="pre">#include</span> <span class="pre">"python.h"</span></tt>
|
||||
directly in a translation unit of a program using Boost.Python,
|
||||
use <tt class="docutils literal"><span class="pre">#include</span> <span class="pre">"boost/python/detail/wrap_python.hpp"</span></tt> instead.
|
||||
It handles several issues necessary for use with Boost.Python,
|
||||
one of which is mentioned in the next section.</li>
|
||||
<li>Be sure not to <tt class="docutils literal"><span class="pre">#include</span></tt> any system headers before
|
||||
<tt class="docutils literal"><span class="pre">wrap_python.hpp</span></tt>. This restriction is actually imposed by
|
||||
Python, or more properly, by Python's interaction with your
|
||||
operating system. See
|
||||
<a class="reference external" href="http://docs.python.org/ext/simpleExample.html">http://docs.python.org/ext/simpleExample.html</a> for details.</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="section" id="python-debugging-builds">
|
||||
<span id="id19"></span><span id="python-debugging"></span><h1><a class="toc-backref" href="#id40">8 Python Debugging Builds</a></h1>
|
||||
<p>Python can be built in a special “python debugging” configuration
|
||||
that adds extra checks and instrumentation that can be very useful
|
||||
for developers of extension modules. The data structures used by
|
||||
the debugging configuration contain additional members, so <strong>a
|
||||
Python executable built with python debugging enabled cannot be
|
||||
used with an extension module or library compiled without it, and
|
||||
vice-versa.</strong></p>
|
||||
<p>Since pre-built “python debugging” versions of the Python
|
||||
executable and libraries are not supplied with most distributions
|
||||
of Python,<a class="footnote-reference" href="#get-debug-build" id="id20"><sup>7</sup></a> and we didn't want to force our users
|
||||
to build them, Boost.Build does not automatically enable python
|
||||
debugging in its <tt class="docutils literal"><span class="pre">debug</span></tt> build variant (which is the default).
|
||||
Instead there is a special build property called
|
||||
<tt class="docutils literal"><span class="pre">python-debugging</span></tt> that, when used as a build property, will
|
||||
define the right preprocessor symbols and select the right
|
||||
libraries to link with.</p>
|
||||
<p>On unix-variant platforms, the debugging versions of Python's data
|
||||
structures will only be used if the symbol <tt class="docutils literal"><span class="pre">Py_DEBUG</span></tt> is defined.
|
||||
On many windows compilers, when extension modules are built with
|
||||
the preprocessor symbol <tt class="docutils literal"><span class="pre">_DEBUG</span></tt>, Python defaults to force
|
||||
linking with a special debugging version of the Python DLL. Since
|
||||
that symbol is very commonly used even when Python is not present,
|
||||
Boost.Python temporarily undefines _DEBUG when Python.h
|
||||
is #included from <tt class="docutils literal"><span class="pre">boost/python/detail/wrap_python.hpp</span></tt> - unless
|
||||
<tt class="docutils literal"><span class="pre">BOOST_DEBUG_PYTHON</span></tt> is defined. The upshot is that if you want
|
||||
“python debugging”and you aren't using Boost.Build, you should make
|
||||
sure <tt class="docutils literal"><span class="pre">BOOST_DEBUG_PYTHON</span></tt> is defined, or python debugging will be
|
||||
suppressed.</p>
|
||||
</div>
|
||||
<div class="section" id="testing-boost-python">
|
||||
<h1><a class="toc-backref" href="#id41">9 Testing Boost.Python</a></h1>
|
||||
<p>To run the full test suite for Boost.Python, invoke <tt class="docutils literal"><span class="pre">bjam</span></tt> in the
|
||||
<tt class="docutils literal"><span class="pre">libs/python/test</span></tt> subdirectory of your Boost distribution.</p>
|
||||
</div>
|
||||
<div class="section" id="notes-for-mingw-and-cygwin-with-mno-cygwin-gcc-users">
|
||||
<h1><a class="toc-backref" href="#id42">10 Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users</a></h1>
|
||||
<p>If you are using a version of Python prior to 2.4.1 with a MinGW
|
||||
prior to 3.0.0 (with binutils-2.13.90-20030111-1), 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 class="reference external" href="http://www.python.org/doc/current/inst/index.html">Installing
|
||||
Python Modules</a> to create <tt class="docutils literal"><span class="pre">libpythonXX.a</span></tt>, where <tt class="docutils literal"><span class="pre">XX</span></tt>
|
||||
corresponds to the major and minor version numbers of your Python
|
||||
installation.</p>
|
||||
<hr class="docutils" />
|
||||
<table class="docutils footnote" frame="void" id="id22" rules="none">
|
||||
<colgroup><col class="label" /><col /></colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td class="label"><a class="fn-backref" href="#id2">[1]</a></td><td>Note that although we tested earlier versions of
|
||||
Boost.Python with Python 2.2, and we don't <em>think</em> we've done
|
||||
anything to break compatibility, this release of Boost.Python
|
||||
may not have been tested with versions of Python earlier than
|
||||
2.4, so we're not 100% sure that python 2.2 and 2.3 are
|
||||
supported.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="docutils footnote" frame="void" id="naming" rules="none">
|
||||
<colgroup><col class="label" /><col /></colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td class="label"><a class="fn-backref" href="#id17">[2]</a></td><td><p class="first">Information about how to identify the
|
||||
static and dynamic builds of Boost.Python:</p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference external" href="../../../more/getting_started/windows.html#library-naming">on Windows</a></li>
|
||||
<li><a class="reference external" href="../../../more/getting_started/unix-variants.html#library-naming">on Unix variants</a></li>
|
||||
</ul>
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="docutils footnote" frame="void" id="toolset-specific" rules="none">
|
||||
<colgroup><col class="label" /><col /></colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td class="label"><a class="fn-backref" href="#id18">[3]</a></td><td>Because of the way most *nix platforms
|
||||
share symbols among dynamically-loaded objects, I'm not certain
|
||||
that extension modules built with different compiler toolsets
|
||||
will always use different copies of the Boost.Python library
|
||||
when loaded into the same Python instance. Not using different
|
||||
libraries could be a good thing if the compilers have compatible
|
||||
ABIs, because extension modules built with the two libraries
|
||||
would be interoperable. Otherwise, it could spell disaster,
|
||||
since an extension module and the Boost.Python library would
|
||||
have different ideas of such things as class layout. I would
|
||||
appreciate someone doing the experiment to find out what
|
||||
happens.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="docutils footnote" frame="void" id="overwrite" rules="none">
|
||||
<colgroup><col class="label" /><col /></colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td class="label"><a class="fn-backref" href="#id13">[4]</a></td><td><tt class="docutils literal"><span class="pre">configure</span></tt> overwrites the existing
|
||||
<tt class="docutils literal"><span class="pre">user-config.jam</span></tt> in your home directory
|
||||
(if any) after making a backup of the old version.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="docutils footnote" frame="void" id="flavor" rules="none">
|
||||
<colgroup><col class="label" /><col /></colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td class="label"><a class="fn-backref" href="#id15">[5]</a></td><td>Note that the <tt class="docutils literal"><span class="pre"><target-os>cygwin</span></tt> feature is
|
||||
different from the <tt class="docutils literal"><span class="pre"><flavor>cygwin</span></tt> subfeature of the <tt class="docutils literal"><span class="pre">gcc</span></tt>
|
||||
toolset, and you might need handle both explicitly if you also
|
||||
have a MinGW GCC installed.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="docutils footnote" frame="void" id="home-dir" rules="none">
|
||||
<colgroup><col class="label" /><col /></colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td class="label"><a class="fn-backref" href="#id11">[6]</a></td><td><p class="first">Windows users, your home directory can be
|
||||
found by typing:</p>
|
||||
<pre class="literal-block">
|
||||
ECHO %HOMEDRIVE%%HOMEPATH%
|
||||
</pre>
|
||||
<p class="last">into a <a class="reference external" href="../../../more/getting_started/windows.html#command-prompt">command prompt</a> window.</p>
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="docutils footnote" frame="void" id="get-debug-build" rules="none">
|
||||
<colgroup><col class="label" /><col /></colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td class="label"><a class="fn-backref" href="#id20">[7]</a></td><td>On Unix and similar platforms, a debugging
|
||||
python and associated libraries are built by adding
|
||||
<tt class="docutils literal"><span class="pre">--with-pydebug</span></tt> when configuring the Python build. On
|
||||
Windows, the debugging version of Python is generated by
|
||||
the "Win32 Debug" target of the Visual Studio project in the
|
||||
PCBuild subdirectory of a full Python source code distribution.
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<hr class="footer" />
|
||||
<a class="reference external" href="./building.rst">View document source</a>.
|
||||
Generated on: 2007-07-02 13:46 UTC.
|
||||
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
||||
|
||||
<p>
|
||||
<li>A comprehensive test of Boost.Python features. This test builds
|
||||
a Boost.Python extension module, then runs Python to import the
|
||||
module, and runs a series of tests on it using <tt><a href=
|
||||
"../test/doctest.py">doctest</a></tt>. Source code for the module
|
||||
and tests is available in the Boost subdirectory
|
||||
<tt>libs/python/test</tt>.
|
||||
|
||||
<p>
|
||||
<li>Various examples from the Boost subdirectory
|
||||
<tt>libs/python/example</tt>.
|
||||
All these examples include a doctest modeled
|
||||
on the comprehensive test above.
|
||||
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
There is a group of makefiles with support for simultaneous
|
||||
compilation on multiple platforms and a consistent set of
|
||||
features that build the <tt>boost_python</tt> library for static
|
||||
linking, the comprehensive test, and all examples in
|
||||
<tt>libs/python/example</tt>:
|
||||
|
||||
<ul>
|
||||
<li><a href="../build/vc60.mak">vc60.mak</a>:
|
||||
Visual C++ 6.0 Service Pack 4
|
||||
|
||||
<li><a href="../build/mingw32.mak">mingw32.mak</a>:
|
||||
mingw32 (Win32-targeted) gcc 2.95.2
|
||||
|
||||
<li><a href="../build/linux_gcc.mak">linux_gcc.mak</a>:
|
||||
gcc 2.95.2 on Linux/Unix
|
||||
|
||||
<li><a href="../build/tru64_cxx.mak">tru64_cxx.mak</a>:
|
||||
Compaq Alpha using the Compaq cxx compiler
|
||||
|
||||
<li><a href="../build/irix_CC.mak">irix_CC.mak</a>:
|
||||
Silicon Graphics IRIX 6.5 CC compiler
|
||||
|
||||
</ul>
|
||||
<a href="http://cctbx.sourceforge.net/page_installation_adv.html#installation_boost_python"
|
||||
>Usage of these makefiles is described here.</a>
|
||||
|
||||
<hr>
|
||||
There is another group of makefiles for GNU make.
|
||||
These makefiles are less redundant than the makefiles
|
||||
in the group above,
|
||||
but the list of compilation targets is not as complete
|
||||
and there is no support for simultaneous compilation
|
||||
on multiple platforms.
|
||||
|
||||
<ul>
|
||||
<li><a href="../build/como.mak">como.mak</a>:
|
||||
Comeau C++ on Linux
|
||||
|
||||
<li><a href="../build/gcc.mak">gcc.mak</a>:
|
||||
GCC on Linux/Unix.
|
||||
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
A project workspace for Microsoft Visual Studio is provided at <tt><a
|
||||
href="../build/build.dsw">libs/python/build/build.dsw</a></tt>. The
|
||||
include paths for this project may need to be changed for your
|
||||
installation. They currently assume that python has been installed at
|
||||
<tt>c:\tools\python</tt>. Three configurations of all targets are
|
||||
supported:
|
||||
|
||||
<ul>
|
||||
<li>Release (optimization, <tt>-DNDEBUG</tt>)
|
||||
|
||||
<li>Debug (no optimization <tt>-D_DEBUG</tt>)
|
||||
|
||||
<li>DebugPython (no optimization, <tt>-D_DEBUG
|
||||
-DBOOST_DEBUG_PYTHON</tt>)
|
||||
</ul>
|
||||
|
||||
<p>When extension modules are built with Visual C++ using
|
||||
<tt>-D_DEBUG</tt>, Python defaults to <i>force</i> 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 <tt><a href=
|
||||
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a></tt>
|
||||
to temporarily undefine <tt>_DEBUG</tt> when <tt>Python.h</tt> is
|
||||
<tt>#include</tt>d.
|
||||
|
||||
<p>If you want the extra runtime checks available with the debugging
|
||||
version of the library, <tt>#define BOOST_DEBUG_PYTHON</tt> to
|
||||
re-enable library forcing, and link with the DebugPython version of
|
||||
<tt>boost_python.lib</tt>. You'll need to get the debugging version
|
||||
of the Python executable (<tt>python_d.exe</tt>) and DLL
|
||||
(<tt>python20_d.dll</tt> or <tt>python15_d.dll</tt>). The Python
|
||||
sources include project files for building these. If you <a href=
|
||||
"http://www.python.org">download</a> them, change the name of the
|
||||
top-level directory to <tt>src</tt>, and install it under
|
||||
<tt>c:\tools\python</tt>, the workspace supplied by Boost.Python will
|
||||
be able to use it without modification. Just open
|
||||
<tt>c:\tools\python\src\pcbuild\pcbuild.dsw</tt> and invoke "build
|
||||
all" to generate all the debugging targets.
|
||||
|
||||
<p>If you do not <tt>#define BOOST_DEBUG_PYTHON</tt>, be sure that
|
||||
any source files <tt>#include <<a href=
|
||||
"../../../boost/python/detail/wrap_python.hpp">boost/python/detail/wrap_python.hpp</a>></tt>
|
||||
instead of the usual <tt>Python.h</tt>, or you will have link
|
||||
incompatibilities.<br>
|
||||
|
||||
<hr>
|
||||
If your platform isn't directly supported, you can build a static
|
||||
library from the following source files (in the Boost subdirectory
|
||||
<tt>libs/python/src</tt>), or compile them directly and link the
|
||||
resulting objects into your extension module:
|
||||
|
||||
<ul>
|
||||
<li><a href=
|
||||
"../../../libs/python/src/classes.cpp">classes.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/conversions.cpp">conversions.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/cross_module.cpp">cross_module.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/extension_class.cpp">extension_class.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/functions.cpp">functions.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/init_function.cpp">init_function.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/module_builder.cpp">module_builder.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/objects.cpp">objects.cpp</a>
|
||||
|
||||
<li><a href=
|
||||
"../../../libs/python/src/types.cpp">types.cpp</a>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
Next: <a href="enums.html">Wrapping Enums</a> Previous: <a href=
|
||||
"under-the-hood.html">A Peek Under the Hood</a> Up: <a href=
|
||||
"index.html">Top</a>
|
||||
|
||||
<hr>
|
||||
<p>© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided ``as is'' without
|
||||
express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.
|
||||
|
||||
<p>Updated: Apr 17, 2001 (R.W. Grosse-Kunstleve)
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
680
doc/building.rst
Normal file
@@ -0,0 +1,680 @@
|
||||
.. Copyright David Abrahams 2006. Distributed under the Boost
|
||||
.. Software License, Version 1.0. (See accompanying
|
||||
.. file LICENSE_1_0.txt or copy at
|
||||
.. http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
==============================================
|
||||
|(logo)|__ Boost.Python Build and Test HOWTO
|
||||
==============================================
|
||||
|
||||
.. |(logo)| image:: ../../../boost.png
|
||||
:alt: Boost C++ Libraries:
|
||||
:class: boost-logo
|
||||
|
||||
__ ../index.html
|
||||
|
||||
|
||||
.. section-numbering::
|
||||
:depth: 2
|
||||
|
||||
.. contents:: Contents
|
||||
:depth: 2
|
||||
:class: sidebar small
|
||||
|
||||
.. |newer| replace:: *newer*
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
Boost.Python requires `Python 2.2`_ [#2.2]_ *or* |newer|__.
|
||||
|
||||
.. _Python 2.2: http://www.python.org/2.2
|
||||
__ http://www.python.org
|
||||
|
||||
Background
|
||||
==========
|
||||
|
||||
There are two basic models for combining C++ and Python:
|
||||
|
||||
- extending_, in which the end-user launches the Python interpreter
|
||||
executable and imports Python “extension modules” written in C++.
|
||||
Think of taking a library written in C++ and giving it a Python
|
||||
interface so Python programmers can use it. From Python, these
|
||||
modules look just like regular Python modules.
|
||||
|
||||
- embedding_, in which the end-user launches a program written
|
||||
in C++ that in turn invokes the Python interpreter as a library
|
||||
subroutine. Think of adding scriptability to an existing
|
||||
application.
|
||||
|
||||
.. _extending: http://www.python.org/doc/current/ext/intro.html
|
||||
.. _embedding: http://www.python.org/doc/current/ext/embedding.html
|
||||
|
||||
The key distinction between extending and embedding is the location
|
||||
of the C++ ``main()`` function: in the Python interpreter executable,
|
||||
or in some other program, respectively. Note that even when
|
||||
embedding Python in another program, `extension modules are often
|
||||
the best way to make C/C++ functionality accessible to Python
|
||||
code`__, so the use of extension modules is really at the heart of
|
||||
both models.
|
||||
|
||||
__ http://www.python.org/doc/current/ext/extending-with-embedding.html
|
||||
|
||||
Except in rare cases, extension modules are built as
|
||||
dynamically-loaded libraries with a single entry point, which means
|
||||
you can change them without rebuilding either the other extension
|
||||
modules or the executable containing ``main()``.
|
||||
|
||||
.. _quickstart:
|
||||
|
||||
No-Install Quickstart
|
||||
=====================
|
||||
|
||||
There is no need to “install Boost” in order to get started using
|
||||
Boost.Python. These instructions use Boost.Build_ projects,
|
||||
which will build those binaries as soon as they're needed. Your
|
||||
first tests may take a little longer while you wait for
|
||||
Boost.Python to build, but doing things this way will save you from
|
||||
worrying about build intricacies like which library binaries to use
|
||||
for a specific compiler configuration and figuring out the right
|
||||
compiler options to use yourself.
|
||||
|
||||
.. .. raw:: html
|
||||
|
||||
<div style="width:50%">
|
||||
|
||||
.. Note:: Of course it's possible to use other build systems to
|
||||
build Boost.Python and its extensions, but they are not
|
||||
officially supported by Boost. Moreover **99% of all “I can't
|
||||
build Boost.Python” problems come from trying to use another
|
||||
build system** without first following these instructions.
|
||||
|
||||
If you want to use another system anyway, we suggest that you
|
||||
follow these instructions, and then invoke ``bjam`` with the
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
``-a -o``\ *filename*
|
||||
|
||||
options to dump the build commands it executes to a file, so
|
||||
you can see what your alternate build system needs to do.
|
||||
|
||||
.. .. raw:: html
|
||||
|
||||
</div>
|
||||
|
||||
.. _Boost.Build: ../../../tools/build/index.html
|
||||
|
||||
Basic Procedure
|
||||
---------------
|
||||
|
||||
1. Get Boost; see sections 1 and 2 [`Unix/Linux`__, `Windows`__\ ] of the
|
||||
Boost `Getting Started Guide`_.
|
||||
|
||||
__ ../../../more/getting_started/unix-variants.html#get-boost
|
||||
__ ../../../more/getting_started/windows.html#get-boost
|
||||
|
||||
2. Get the ``bjam`` build driver. See section 5 [`Unix/Linux`__,
|
||||
`Windows`__\ ] of the Boost `Getting Started Guide`_.
|
||||
|
||||
__ ../../../more/getting_started/unix-variants.html#prepare-to-use-a-boost-library-binary
|
||||
__ ../../../more/getting_started/windows.html#prepare-to-use-a-boost-library-binary
|
||||
|
||||
|
||||
3. cd into the ``libs/python/example/quickstart/`` directory of your
|
||||
Boost installation, which contains a small example project.
|
||||
|
||||
4. Invoke ``bjam``. Replace the “\ ``stage``\ “ argument from the
|
||||
example invocation from section 5 of the `Getting Started
|
||||
Guide`_ with “\ ``test``\ ,“ to build all the test targets. Also add
|
||||
the argument “\ ``--verbose-test``\ ” to see the output generated by
|
||||
the tests when they are run.
|
||||
|
||||
On Windows, your ``bjam`` invocation might look something like:
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
C:\\boost_1_34_0\\…\\quickstart> **bjam toolset=msvc --verbose-test test**
|
||||
|
||||
and on Unix variants, perhaps,
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
~/boost_1_34_0/…/quickstart$ **bjam toolset=gcc --verbose-test test**
|
||||
|
||||
.. Admonition:: Note to Windows Users
|
||||
|
||||
For the sake of concision, the rest of this guide will use
|
||||
unix-style forward slashes in pathnames instead of the
|
||||
backslashes with which you may be more familiar. The forward
|
||||
slashes should work everywhere except in `Command Prompt`_
|
||||
windows, where you should use backslashes.
|
||||
|
||||
.. _Command Prompt: ../../../more/getting_started/windows.html#command-prompt
|
||||
|
||||
If you followed this procedure successfully, you will have built an
|
||||
extension module called ``extending`` and tested it by running a
|
||||
Python script called ``test_extending.py``. You will also have
|
||||
built and run a simple application called ``embedding`` that embeds
|
||||
python.
|
||||
|
||||
.. _Getting Started Guide: ../../../more/getting_started/index.html
|
||||
|
||||
In Case of Trouble
|
||||
------------------
|
||||
|
||||
If you're seeing lots of compiler and/or linker error messages,
|
||||
it's probably because Boost.Build is having trouble finding your
|
||||
Python installation. You might want to pass the
|
||||
``--debug-configuration`` option to ``bjam`` the first few times
|
||||
you invoke it, to make sure that Boost.Build is correctly locating
|
||||
all the parts of your Python installation. If it isn't, consider
|
||||
`Configuring Boost.Build`_ as detailed below.
|
||||
|
||||
If you're still having trouble, Someone on one of the following
|
||||
mailing lists may be able to help:
|
||||
|
||||
* The `Boost.Build mailing list`__ for issues related to Boost.Build
|
||||
* The Python `C++ Sig`__ for issues specifically related to Boost.Python
|
||||
|
||||
__ http://www.boost.org/more/mailing_lists.htm#jamboost
|
||||
__ http://www.boost.org/more/mailing_lists.htm#cplussig
|
||||
|
||||
In Case Everything Seemed to Work
|
||||
---------------------------------
|
||||
|
||||
Rejoice! If you're new to Boost.Python, at this point it might be
|
||||
a good idea to ignore build issues for a while and concentrate on
|
||||
learning the library by going through the tutorial_ and perhaps
|
||||
some of the `reference documentation`_, trying out what you've
|
||||
learned about the API by modifying the quickstart project.
|
||||
|
||||
.. _reference documentation: v2/reference.html
|
||||
.. _tutorial: tutorial/index.html
|
||||
|
||||
Modifying the Example Project
|
||||
-----------------------------
|
||||
|
||||
If you're content to keep your extension module forever in one
|
||||
source file called |extending.cpp|_, inside your Boost
|
||||
distribution, and import it forever as ``extending``, then you can
|
||||
stop here. However, it's likely that you will want to make a few
|
||||
changes. There are a few things you can do without having to learn
|
||||
Boost.Build_ in depth.
|
||||
|
||||
The project you just built is specified in two files in the current
|
||||
directory: |boost-build.jam|_, which tells ``bjam`` where it can
|
||||
find the interpreted code of the Boost build system, and
|
||||
|Jamroot|_, which describes the targets you just built. These
|
||||
files are heavily commented, so they should be easy to modify.
|
||||
Take care, however, to preserve whitespace. Punctuation such as
|
||||
``;`` will not be recognized as intended by ``bjam`` if it is not
|
||||
surrounded by whitespace.
|
||||
|
||||
.. |boost-build.jam| replace:: ``boost-build.jam``
|
||||
.. _boost-build.jam: ../example/quickstart/boost-build.jam
|
||||
|
||||
.. |Jamroot| replace:: ``Jamroot``
|
||||
.. _Jamroot: ../example/quickstart/Jamroot
|
||||
|
||||
.. |extending.cpp| replace:: ``extending.cpp``
|
||||
.. _extending.cpp: ../example/quickstart/extending.cpp
|
||||
|
||||
Relocate the Project
|
||||
....................
|
||||
|
||||
You'll probably want to copy this project elsewhere so you can
|
||||
change it without modifying your Boost distribution. To do that,
|
||||
simply
|
||||
|
||||
a. copy the entire ``libs/python/example/quickstart/`` directory
|
||||
into a new directory.
|
||||
|
||||
b. In the new copies of |boost-build.jam|_ and |Jamroot|_, locate
|
||||
the relative path near the top of the file that is clearly
|
||||
marked by a comment, and edit that path so that it refers to the
|
||||
same directory your Boost distribution as it referred to when
|
||||
the file was in its original location in the
|
||||
``libs/python/example/quickstart/`` directory.
|
||||
|
||||
For example, if you moved the project from
|
||||
``/home/dave/boost_1_34_0/libs/python/example/quickstart`` to
|
||||
``/home/dave/my-project``, you could change the first path in
|
||||
|boost-build.jam|_ from
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
**../../../..**\ /tools/build/v2
|
||||
|
||||
to
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
**/home/dave/boost_1_34_0**\ /tools/build/v2
|
||||
|
||||
and change the first path in |Jamroot|_ from
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
**../../../..**
|
||||
|
||||
to
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
**/home/dave/boost_1_34_0**
|
||||
|
||||
Add New or Change Names of Existing Source Files
|
||||
................................................
|
||||
|
||||
The names of additional source files involved in building your
|
||||
extension module or embedding application can be listed in
|
||||
|Jamroot|_ right alongside ``extending.cpp`` or ``embedding.cpp``
|
||||
respectively. Just be sure to leave whitespace around each
|
||||
filename::
|
||||
|
||||
… file1.cpp file2.cpp file3.cpp …
|
||||
|
||||
Naturally, if you want to change the name of a source file you can
|
||||
tell Boost.Build about it by editing the name in |Jamroot|_.
|
||||
|
||||
Change the Name of your Extension Module
|
||||
........................................
|
||||
|
||||
The name of the extension module is determined by two things:
|
||||
|
||||
1. the name in |Jamroot|_ immediately following ``python-extension``, and
|
||||
2. the name passed to ``BOOST_PYTHON_MODULE`` in |extending.cpp|_.
|
||||
|
||||
To change the name of the extension module from ``extending`` to
|
||||
``hello``, you'd edit |Jamroot|_, changing
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
python-extension **extending** : extending.cpp ;
|
||||
|
||||
to
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
python-extension **hello** : extending.cpp ;
|
||||
|
||||
and you'd edit extending.cpp, changing
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
BOOST_PYTHON_MODULE(\ **extending**\ )
|
||||
|
||||
to
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
BOOST_PYTHON_MODULE(\ **hello**\ )
|
||||
|
||||
Installing Boost.Python on your System
|
||||
======================================
|
||||
|
||||
Since Boost.Python is a separately-compiled (as opposed to
|
||||
`header-only`_) library, its user relies on the services of a
|
||||
Boost.Python library binary.
|
||||
|
||||
.. _header-only: ../../../more/getting_started/windows.html#header-only-libraries
|
||||
|
||||
If you need a regular installation of the Boost.Python library
|
||||
binaries on your system, the Boost `Getting Started Guide`_ will
|
||||
walk you through the steps of creating one. If building binaries
|
||||
from source, you might want to supply the ``--with-python``
|
||||
argument to ``bjam`` (or the ``--with-libraries=python`` argument
|
||||
to ``configure``), so only the Boost.Python binary will be built,
|
||||
rather than all the Boost binaries.
|
||||
|
||||
|
||||
Configuring Boost.Build
|
||||
=======================
|
||||
|
||||
As described in the `Boost.Build reference manual`__, a file called
|
||||
``user-config.jam`` in your home directory [#home-dir]_ is used to
|
||||
specify the tools and libraries available to the build system. You
|
||||
may need to create or edit ``user-config.jam`` to tell Boost.Build
|
||||
how to invoke Python, ``#include`` its headers, and link with its
|
||||
libraries.
|
||||
|
||||
__ http://www.boost.orgdoc/html/bbv2/advanced.html#bbv2.advanced.configuration
|
||||
|
||||
.. Admonition:: Users of Unix-Variant OSes
|
||||
|
||||
If you are using a unix-variant OS and you ran Boost's
|
||||
``configure`` script, it may have generated a
|
||||
``user-config.jam`` for you. [#overwrite]_ If your ``configure``\
|
||||
/\ ``make`` sequence was successful and Boost.Python binaries
|
||||
were built, your ``user-config.jam`` file is probably already
|
||||
correct.
|
||||
|
||||
If you have one fairly “standard” python installation for your
|
||||
platform, you might not need to do anything special to describe it. If
|
||||
you haven't configured python in ``user-config.jam`` (and you don't
|
||||
specify ``--without-python`` on the Boost.Build command line),
|
||||
Boost.Build will automatically execute the equivalent of ::
|
||||
|
||||
import toolset : using ;
|
||||
using python ;
|
||||
|
||||
which automatically looks for Python in the most likely places.
|
||||
However, that only happens when using the Boost.Python project file
|
||||
(e.g. when referred to by another project as in the quickstart_
|
||||
method). If instead you are linking against separately-compiled
|
||||
Boost.Python binaries, you should set up a ``user-config.jam`` file
|
||||
with at least the minimal incantation above.
|
||||
|
||||
Python Configuration Parameters
|
||||
-------------------------------
|
||||
|
||||
If you have several versions of Python installed, or Python is
|
||||
installed in an unusual way, you may want to supply any or all of
|
||||
the following optional parameters to ``using python``.
|
||||
|
||||
version
|
||||
the version of Python to use. Should be in Major.Minor
|
||||
format, for example, ``2.3``. Do not include the subminor
|
||||
version (i.e. *not* ``2.5.1``). If you have multiple Python
|
||||
versions installed, the version will usually be the only
|
||||
configuration argument required.
|
||||
|
||||
cmd-or-prefix
|
||||
preferably, a command that invokes a Python interpreter.
|
||||
Alternatively, the installation prefix for Python libraries and
|
||||
header files. Only use the alternative formulation if there is
|
||||
no appropriate Python executable available.
|
||||
|
||||
includes
|
||||
the ``#include`` paths for Python headers. Normally the correct
|
||||
path(s) will be automatically deduced from ``version`` and/or
|
||||
``cmd-or-prefix``.
|
||||
|
||||
libraries
|
||||
the path to Python library binaries. On MacOS/Darwin,
|
||||
you can also pass the path of the Python framework. Normally the
|
||||
correct path(s) will be automatically deduced from ``version``
|
||||
and/or ``cmd-or-prefix``.
|
||||
|
||||
condition
|
||||
if specified, should be a set of Boost.Build
|
||||
properties that are matched against the build configuration when
|
||||
Boost.Build selects a Python configuration to use. See examples
|
||||
below for details.
|
||||
|
||||
extension-suffix
|
||||
A string to append to the name of extension
|
||||
modules before the true filename extension. You almost certainly
|
||||
don't need to use this. Usually this suffix is only used when
|
||||
targeting a Windows debug build of Python, and will be set
|
||||
automatically for you based on the value of the
|
||||
|python-debugging|_ feature. However, at least one Linux
|
||||
distribution (Ubuntu Feisty Fawn) has a specially configured
|
||||
`python-dbg`__ package that claims to use such a suffix.
|
||||
|
||||
.. |python-debugging| replace:: ``<python-debugging>``
|
||||
|
||||
__ https://wiki.ubuntu.com/PyDbgBuilds
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Note that in the examples below, case and *especially whitespace* are
|
||||
significant.
|
||||
|
||||
- If you have both python 2.5 and python 2.4 installed,
|
||||
``user-config.jam`` might contain::
|
||||
|
||||
using python : 2.5 ; # Make both versions of Python available
|
||||
|
||||
using python : 2.4 ; # To build with python 2.4, add python=2.4
|
||||
# to your command line.
|
||||
|
||||
The first version configured (2.5) becomes the default. To build
|
||||
against python 2.4, add ``python=2.4`` to the ``bjam`` command line.
|
||||
|
||||
- If you have python installed in an unusual location, you might
|
||||
supply the path to the interpreter in the ``cmd-or-prefix``
|
||||
parameter::
|
||||
|
||||
using python : : /usr/local/python-2.6-beta/bin/python ;
|
||||
|
||||
- If you have a separate build of Python for use with a particular
|
||||
toolset, you might supply that toolset in the ``condition``
|
||||
parameter::
|
||||
|
||||
using python ; # use for most toolsets
|
||||
|
||||
# Use with Intel C++ toolset
|
||||
using python
|
||||
: # version
|
||||
: c:\\Devel\\Python-2.5-IntelBuild\\PCBuild\\python # cmd-or-prefix
|
||||
: # includes
|
||||
: # libraries
|
||||
: <toolset>intel # condition
|
||||
;
|
||||
|
||||
|
||||
- If you have downloaded the Python sources and built both the
|
||||
normal and the “\ `python debugging`_\ ” builds from source on
|
||||
Windows, you might see::
|
||||
|
||||
using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python ;
|
||||
using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python_d
|
||||
: # includes
|
||||
: # libs
|
||||
: <python-debugging>on ;
|
||||
|
||||
- You can set up your user-config.jam so a bjam built under Windows
|
||||
can build/test both Windows and Cygwin_ python extensions. Just pass
|
||||
``<target-os>cygwin`` in the ``condition`` parameter
|
||||
for the cygwin python installation::
|
||||
|
||||
# windows installation
|
||||
using python ;
|
||||
|
||||
# cygwin installation
|
||||
using python : : c:\\cygwin\\bin\\python2.5 : : : <target-os>cygwin ;
|
||||
|
||||
when you put target-os=cygwin in your build request, it should build
|
||||
with the cygwin version of python: [#flavor]_
|
||||
|
||||
bjam target-os=cygwin toolset=gcc
|
||||
|
||||
This is supposed to work the other way, too (targeting windows
|
||||
python with a Cygwin_ bjam) but it seems as though the support in
|
||||
Boost.Build's toolsets for building that way is broken at the
|
||||
time of this writing.
|
||||
|
||||
- Note that because of `the way Boost.Build currently selects target
|
||||
alternatives`__, you might have be very explicit in your build
|
||||
requests. For example, given::
|
||||
|
||||
using python : 2.5 ; # a regular windows build
|
||||
using python : 2.4 : : : : <target-os>cygwin ;
|
||||
|
||||
building with ::
|
||||
|
||||
bjam target-os=cygwin
|
||||
|
||||
will yield an error. Instead, you'll need to write::
|
||||
|
||||
bjam target-os=cygwin/python=2.4
|
||||
|
||||
.. _Cygwin: http://cygwin.com
|
||||
|
||||
__ http://zigzag.cs.msu.su/boost.build/wiki/AlternativeSelection
|
||||
|
||||
Choosing a Boost.Python Library Binary
|
||||
======================================
|
||||
|
||||
If—instead of letting Boost.Build construct and link with the right
|
||||
libraries automatically—you choose to use a pre-built Boost.Python
|
||||
library, you'll need to think about which one to link with. The
|
||||
Boost.Python binary comes in both static and dynamic flavors. Take
|
||||
care to choose the right flavor for your application. [#naming]_
|
||||
|
||||
The Dynamic Binary
|
||||
------------------
|
||||
|
||||
The dynamic library is the safest and most-versatile choice:
|
||||
|
||||
- A single copy of the library code is used by all extension
|
||||
modules built with a given toolset. [#toolset-specific]_
|
||||
|
||||
- The library contains a type conversion registry. Because one
|
||||
registry is shared among all extension modules, instances of a
|
||||
class exposed to Python in one dynamically-loaded extension
|
||||
module can be passed to functions exposed in another such module.
|
||||
|
||||
The Static Binary
|
||||
-----------------
|
||||
|
||||
It might be appropriate to use the static Boost.Python library in
|
||||
any of the following cases:
|
||||
|
||||
- You are extending_ python and the types exposed in your
|
||||
dynamically-loaded extension module don't need to be used by any
|
||||
other Boost.Python extension modules, and you don't care if the
|
||||
core library code is duplicated among them.
|
||||
|
||||
- You are embedding_ python in your application and either:
|
||||
|
||||
- You are targeting a Unix variant OS other than MacOS or AIX,
|
||||
where the dynamically-loaded extension modules can “see” the
|
||||
Boost.Python library symbols that are part of the executable.
|
||||
|
||||
- Or, you have statically linked some Boost.Python extension
|
||||
modules into your application and you don't care if any
|
||||
dynamically-loaded Boost.Python extension modules are able to
|
||||
use the types exposed by your statically-linked extension
|
||||
modules (and vice-versa).
|
||||
|
||||
``#include`` Issues
|
||||
===================
|
||||
|
||||
1. If you should ever have occasion to ``#include "python.h"``
|
||||
directly in a translation unit of a program using Boost.Python,
|
||||
use ``#include "boost/python/detail/wrap_python.hpp"`` instead.
|
||||
It handles several issues necessary for use with Boost.Python,
|
||||
one of which is mentioned in the next section.
|
||||
|
||||
2. Be sure not to ``#include`` any system headers before
|
||||
``wrap_python.hpp``. This restriction is actually imposed by
|
||||
Python, or more properly, by Python's interaction with your
|
||||
operating system. See
|
||||
http://docs.python.org/ext/simpleExample.html for details.
|
||||
|
||||
.. _python-debugging:
|
||||
.. _python debugging:
|
||||
|
||||
Python Debugging Builds
|
||||
=======================
|
||||
|
||||
Python can be built in a special “python debugging” configuration
|
||||
that adds extra checks and instrumentation that can be very useful
|
||||
for developers of extension modules. The data structures used by
|
||||
the debugging configuration contain additional members, so **a
|
||||
Python executable built with python debugging enabled cannot be
|
||||
used with an extension module or library compiled without it, and
|
||||
vice-versa.**
|
||||
|
||||
Since pre-built “python debugging” versions of the Python
|
||||
executable and libraries are not supplied with most distributions
|
||||
of Python, [#get-debug-build]_ and we didn't want to force our users
|
||||
to build them, Boost.Build does not automatically enable python
|
||||
debugging in its ``debug`` build variant (which is the default).
|
||||
Instead there is a special build property called
|
||||
``python-debugging`` that, when used as a build property, will
|
||||
define the right preprocessor symbols and select the right
|
||||
libraries to link with.
|
||||
|
||||
On unix-variant platforms, the debugging versions of Python's data
|
||||
structures will only be used if the symbol ``Py_DEBUG`` is defined.
|
||||
On many windows compilers, when extension modules are built with
|
||||
the preprocessor symbol ``_DEBUG``, Python defaults to force
|
||||
linking with a special debugging version of the Python DLL. Since
|
||||
that symbol is very commonly used even when Python is not present,
|
||||
Boost.Python temporarily undefines _DEBUG when Python.h
|
||||
is #included from ``boost/python/detail/wrap_python.hpp`` - unless
|
||||
``BOOST_DEBUG_PYTHON`` is defined. The upshot is that if you want
|
||||
“python debugging”and you aren't using Boost.Build, you should make
|
||||
sure ``BOOST_DEBUG_PYTHON`` is defined, or python debugging will be
|
||||
suppressed.
|
||||
|
||||
Testing Boost.Python
|
||||
====================
|
||||
|
||||
To run the full test suite for Boost.Python, invoke ``bjam`` in the
|
||||
``libs/python/test`` subdirectory of your Boost distribution.
|
||||
|
||||
Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users
|
||||
=======================================================
|
||||
|
||||
If you are using a version of Python prior to 2.4.1 with a MinGW
|
||||
prior to 3.0.0 (with binutils-2.13.90-20030111-1), 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 `Installing
|
||||
Python Modules`__ to create ``libpythonXX.a``, where ``XX``
|
||||
corresponds to the major and minor version numbers of your Python
|
||||
installation.
|
||||
|
||||
__ http://www.python.org/doc/current/inst/index.html
|
||||
|
||||
-----------------------------
|
||||
|
||||
.. [#2.2] Note that although we tested earlier versions of
|
||||
Boost.Python with Python 2.2, and we don't *think* we've done
|
||||
anything to break compatibility, this release of Boost.Python
|
||||
may not have been tested with versions of Python earlier than
|
||||
2.4, so we're not 100% sure that python 2.2 and 2.3 are
|
||||
supported.
|
||||
|
||||
.. [#naming] Information about how to identify the
|
||||
static and dynamic builds of Boost.Python:
|
||||
|
||||
* `on Windows`__
|
||||
* `on Unix variants`__
|
||||
|
||||
__ ../../../more/getting_started/windows.html#library-naming
|
||||
__ ../../../more/getting_started/unix-variants.html#library-naming
|
||||
|
||||
.. [#toolset-specific] Because of the way most \*nix platforms
|
||||
share symbols among dynamically-loaded objects, I'm not certain
|
||||
that extension modules built with different compiler toolsets
|
||||
will always use different copies of the Boost.Python library
|
||||
when loaded into the same Python instance. Not using different
|
||||
libraries could be a good thing if the compilers have compatible
|
||||
ABIs, because extension modules built with the two libraries
|
||||
would be interoperable. Otherwise, it could spell disaster,
|
||||
since an extension module and the Boost.Python library would
|
||||
have different ideas of such things as class layout. I would
|
||||
appreciate someone doing the experiment to find out what
|
||||
happens.
|
||||
|
||||
.. [#overwrite] ``configure`` overwrites the existing
|
||||
``user-config.jam`` in your home directory
|
||||
(if any) after making a backup of the old version.
|
||||
|
||||
.. [#flavor] Note that the ``<target-os>cygwin`` feature is
|
||||
different from the ``<flavor>cygwin`` subfeature of the ``gcc``
|
||||
toolset, and you might need handle both explicitly if you also
|
||||
have a MinGW GCC installed.
|
||||
|
||||
.. [#home-dir] Windows users, your home directory can be
|
||||
found by typing::
|
||||
|
||||
ECHO %HOMEDRIVE%%HOMEPATH%
|
||||
|
||||
into a `command prompt`_ window.
|
||||
|
||||
.. [#get-debug-build] On Unix and similar platforms, a debugging
|
||||
python and associated libraries are built by adding
|
||||
``--with-pydebug`` when configuring the Python build. On
|
||||
Windows, the debugging version of Python is generated by
|
||||
the "Win32 Debug" target of the Visual Studio project in the
|
||||
PCBuild subdirectory of a full Python source code distribution.
|
||||
@@ -1,231 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<title>
|
||||
Comparisons with Other Systems
|
||||
</title>
|
||||
<div>
|
||||
<h1>
|
||||
<img width="277" height="86" id="_x0000_i1025" align="center"
|
||||
src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)"><br>
|
||||
Comparisons with
|
||||
Other Systems
|
||||
</h1>
|
||||
|
||||
<h2>CXX</h2>
|
||||
<p>
|
||||
Like Boost.Python, <a href="http://cxx.sourceforge.net/">CXX</a> attempts to
|
||||
provide a C++-oriented interface to Python. In most cases, as with the
|
||||
boost library, it relieves the user from worrying about
|
||||
reference-counts. Both libraries automatically convert thrown C++
|
||||
exceptions into Python exceptions. As far as I can tell, CXX has no
|
||||
support for subclassing C++ extension types in Python. An even
|
||||
more significant difference is that a user's C++ code is still basically
|
||||
``dealing with Python objects'', though they are wrapped in
|
||||
C++ classes. This means such jobs as argument parsing and conversion are
|
||||
still left to be done explicitly by the user.
|
||||
|
||||
<p>
|
||||
CXX claims to interoperate well with the C++ Standard Library
|
||||
(a.k.a. STL) by providing iterators into Python Lists and Dictionaries,
|
||||
but the claim is unfortunately unsupportable. The problem is that in
|
||||
general, access to Python sequence and mapping elements through
|
||||
iterators requires the use of proxy objects as the return value of
|
||||
iterator dereference operations. This usage conflicts with the basic
|
||||
ForwardIterator requirements in <a
|
||||
href="http://anubis.dkuug.dk/jtc1/sc22/open/n2356/lib-iterators.html#lib.forward.iterators">
|
||||
section 24.1.3 of the standard</a> (dereferencing must produce a
|
||||
reference). Although you may be able to use these iterators with some
|
||||
operations in some standard library implementations, it is neither
|
||||
guaranteed to work nor portable.
|
||||
|
||||
<p>
|
||||
As far as I can tell, CXX enables one to write what is essentially
|
||||
idiomatic Python code in C++, manipulating Python objects through the
|
||||
same fully-generic interfaces we use in Python. While you're hardly
|
||||
programming directly to the ``bare metal'' with CXX, it basically
|
||||
presents a ``C++-ized'' version of the Python 'C' API. Some fraction of
|
||||
that capability is available in Boost.Python through <tt><a
|
||||
href="../../../boost/python/objects.hpp">boost/python/objects.hpp</a></tt>,
|
||||
which provides C++ objects corresponding to Python lists, tuples,
|
||||
strings, and dictionaries, and through <tt><a
|
||||
href="../../../boost/python/callback.hpp">boost/python/callback.hpp</a></tt>,
|
||||
which allows you to call back into python with C++ arguments.
|
||||
|
||||
<p>
|
||||
<a href="mailto:dubois1@llnl.gov">Paul F. Dubois</a>, the original
|
||||
author of CXX, has told me that what I've described is only half of the
|
||||
picture with CXX, but I never understood his explanation well-enough to
|
||||
fill in the other half. Here is his response to the commentary above:
|
||||
|
||||
<blockquote>
|
||||
``My intention with CXX was not to do what you are doing. It was to enable a
|
||||
person to write an extension directly in C++ rather than C. I figured others had
|
||||
the wrapping business covered. I thought maybe CXX would provide an easier
|
||||
target language for those making wrappers, but I never explored
|
||||
that.''<br><i>-<a href="mailto:dubois1@llnl.gov">Paul Dubois</a></i>
|
||||
</blockquote>
|
||||
|
||||
<h2>SWIG</h2>
|
||||
<p>
|
||||
<a href= "http://www.swig.org/">SWIG</a> is an impressively mature tool
|
||||
for exporting an existing ANSI 'C' interface into various scripting
|
||||
languages. Swig relies on a parser to read your source code and produce
|
||||
additional source code files which can be compiled into a Python (or
|
||||
Perl or Tcl) extension module. It has been successfully used to create
|
||||
many Python extension modules. Like Boost.Python, SWIG is trying to allow an
|
||||
existing interface to be wrapped with little or no change to the
|
||||
existing code. The documentation says ``SWIG parses a form of ANSI C
|
||||
syntax that has been extended with a number of special directives. As a
|
||||
result, interfaces are usually built by grabbing a header file and
|
||||
tweaking it a little bit.'' For C++ interfaces, the tweaking has often
|
||||
proven to amount to more than just a little bit. One user
|
||||
writes:
|
||||
|
||||
<blockquote> ``The problem with swig (when I used it) is that it
|
||||
couldnt handle templates, didnt do func overloading properly etc. For
|
||||
ANSI C libraries this was fine. But for usual C++ code this was a
|
||||
problem. Simple things work. But for anything very complicated (or
|
||||
realistic), one had to write code by hand. I believe Boost.Python doesn't have
|
||||
this problem[<a href="#sic">sic</a>]... IMHO overloaded functions are very important to
|
||||
wrap correctly.''<br><i>-Prabhu Ramachandran</i>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
By contrast, Boost.Python doesn't attempt to parse C++ - the problem is simply
|
||||
too complex to do correctly. <a name="sic">Technically</a>, one does
|
||||
write code by hand to use Boost.Python. The goal, however, has been to make
|
||||
that code nearly as simple as listing the names of the classes and
|
||||
member functions you want to expose in Python.
|
||||
|
||||
<h2>SIP</h2>
|
||||
<p>
|
||||
<a
|
||||
href="http://www.thekompany.com/projects/pykde/background.php3?dhtml_ok=1">SIP</a>
|
||||
is a system similar to SWIG, though seemingly more
|
||||
C++-oriented. The author says that like Boost.Python, SIP supports overriding
|
||||
extension class member functions in Python subclasses. It appears to
|
||||
have been designed specifically to directly support some features of
|
||||
PyQt/PyKDE, which is its primary client. Documentation is almost
|
||||
entirely missing at the time of this writing, so a detailed comparison
|
||||
is difficult.
|
||||
|
||||
<h2>ILU</h2>
|
||||
<p>
|
||||
<a
|
||||
href="ftp://ftp.parc.xerox.com/pub/ilu/ilu.html">ILU</a>
|
||||
is a very ambitious project which tries to describe a module's interface
|
||||
(types and functions) in terms of an <a
|
||||
href="ftp://ftp.parc.xerox.com/pub/ilu/2.0b1/manual-html/manual_2.html">Interface
|
||||
Specification Language</a> (ISL) so that it can be uniformly interfaced
|
||||
to a wide range of computer languages, including Common Lisp, C++, C,
|
||||
Modula-3, and Python. ILU can parse the ISL to generate a C++ language
|
||||
header file describing the interface, of which the user is expected to
|
||||
provide an implementation. Unlike Boost.Python, this means that the system
|
||||
imposes implementation details on your C++ code at the deepest level. It
|
||||
is worth noting that some of the C++ names generated by ILU are supposed
|
||||
to be reserved to the C++ implementation. It is unclear from the
|
||||
documentation whether ILU supports overriding C++ virtual functions in Python.
|
||||
|
||||
<h2>GRAD</h2>
|
||||
<p>
|
||||
<a
|
||||
href="http://www.python.org/workshops/1996-11/papers/GRAD/html/GRADcover.html">GRAD</a>
|
||||
is another very ambitious project aimed at generating Python wrappers for
|
||||
interfaces written in ``legacy languages'', among which C++ is the first one
|
||||
implemented. Like SWIG, it aims to parse source code and automatically
|
||||
generate wrappers, though it appears to take a more sophisticated approach
|
||||
to parsing in general and C++ in particular, so it should do a much better
|
||||
job with C++. It appears to support function overloading. The
|
||||
documentation is missing a lot of information I'd like to see, so it is
|
||||
difficult to give an accurate and fair assessment. I am left with the
|
||||
following questions:
|
||||
<ul>
|
||||
<li>Does it support overriding of virtual functions?
|
||||
<li>What about overriding private or protected virtual functions (the documentation indicates
|
||||
that only public interfaces are supported)?
|
||||
<li>Which C++ language constructs are supportd?
|
||||
<li>Does it support implicit conversions between wrapped C++ classes that have
|
||||
an inheritance relationship?
|
||||
<li>Does it support smart pointers?
|
||||
</ul>
|
||||
<p>
|
||||
Anyone in the possession of the answers to these questions will earn my
|
||||
gratitude for a write-up <code>;-)</code>
|
||||
|
||||
<h2>Zope ExtensionClasses</h2>
|
||||
<p>
|
||||
<a href="http:http://www.digicool.com/releases/ExtensionClass">
|
||||
ExtensionClasses in Zope</a> use the same underlying mechanism as Boost.Python
|
||||
to support subclassing of extension types in Python, including
|
||||
multiple-inheritance. Both systems support pickling/unpickling of
|
||||
extension class instances in very similar ways. Both systems rely on the
|
||||
same ``<a
|
||||
href="http://www.python.org/workshops/1994-11/BuiltInClasses/Welcome.html">Don
|
||||
Beaudry Hack</a>'' that also inspired Don's MESS System.
|
||||
<p>
|
||||
The major differences are:
|
||||
<ul>
|
||||
<li>Zope is entirely 'C' language-based. It doesn't require a C++
|
||||
compiler, so it's much more portable than Boost.Python, which stresses
|
||||
the limits of even some modern C++ implementations.
|
||||
|
||||
<li>
|
||||
Boost.Python lifts the burden on the user to parse and convert function
|
||||
argument types. Zope provides no such facility.
|
||||
<li>
|
||||
Boost.Python lifts the burden on the user to maintain Python
|
||||
reference-counts.
|
||||
<li>
|
||||
Boost.Python supports function overloading; Zope does not.
|
||||
<li>
|
||||
Boost.Python supplies a simple mechanism for exposing read-only and
|
||||
read/write access to data members of the wrapped C++ type as Python
|
||||
attributes.
|
||||
<li>
|
||||
Writing a Zope ExtensionClass is significantly more complex than
|
||||
exposing a C++ class to python using Boost.Python (mostly a summary of the
|
||||
previous 4 items). <a href=
|
||||
"http://www.digicool.com/releases/ExtensionClass/MultiMapping.html">A
|
||||
Zope Example</a> illustrates the differences.
|
||||
<li>
|
||||
Zope's ExtensionClasses are specifically motivated by ``the need for a
|
||||
C-based persistence mechanism''. Boost.Python's are motivated by the desire
|
||||
to simply reflect a C++ API into Python with as little modification as
|
||||
possible.
|
||||
<li>
|
||||
The following Zope restriction does not apply to Boost.Python: ``At most one
|
||||
base extension direct or indirect super class may define C data
|
||||
members. If an extension subclass inherits from multiple base
|
||||
extension classes, then all but one must be mix-in classes that
|
||||
provide extension methods but no data.''
|
||||
<li>
|
||||
Zope requires use of the somewhat funky inheritedAttribute (search for
|
||||
``inheritedAttribute'' on <a
|
||||
href="http://www.digicool.com/releases/ExtensionClass">this page</a>)
|
||||
method to access base class methods. In Boost.Python, base class methods can
|
||||
be accessed in the usual way by writing
|
||||
``<code>BaseClass.method</code>''.
|
||||
<li>
|
||||
Zope supplies some creative but esoteric idioms such as <a href=
|
||||
"http://www.digicool.com/releases/ExtensionClass/Acquisition.html">
|
||||
Acquisition</a>. No specific support for this is built into Boost.Python.
|
||||
<li>
|
||||
Zope's ComputedAttribute support is designed to be used from Python.
|
||||
<a href="special.html#getter_setter">The analogous feature of
|
||||
Boost.Python</a> can be used from C++ or Python. The feature is arguably
|
||||
easier to use in Boost.Python.
|
||||
</ul>
|
||||
<p>
|
||||
Next: <a href="example1.html">A Simple Example Using Boost.Python</a>
|
||||
Previous: <a href="extending.html">A Brief Introduction to writing Python Extension Modules</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided ``as is'' without
|
||||
express or implied warranty, and with no claim as to its suitability
|
||||
for any purpose.
|
||||
<p>
|
||||
Updated: Mar 6, 2001
|
||||
</div>
|
||||
|
||||
@@ -1,336 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
|
||||
<title>Cross-extension-module dependencies</title>
|
||||
|
||||
<div>
|
||||
|
||||
<img src="../../../c++boost.gif"
|
||||
alt="c++boost.gif (8819 bytes)"
|
||||
align="center"
|
||||
width="277" height="86">
|
||||
|
||||
<hr>
|
||||
<h1>Cross-extension-module dependencies</h1>
|
||||
|
||||
It is good programming practice to organize large projects as modules
|
||||
that interact with each other via well defined interfaces. With
|
||||
Boost.Python it is possible to reflect this organization at the C++
|
||||
level at the Python level. This is, each logical C++ module can be
|
||||
organized as a separate Python extension module.
|
||||
|
||||
<p>
|
||||
At first sight this might seem natural and straightforward. However, it
|
||||
is a fairly complex problem to establish cross-extension-module
|
||||
dependencies while maintaining the same ease of use Boost.Python
|
||||
provides for classes that are wrapped in the same extension module. To
|
||||
a large extent this complexity can be hidden from the author of a
|
||||
Boost.Python extension module, but not entirely.
|
||||
|
||||
<hr>
|
||||
<h2>The recipe</h2>
|
||||
|
||||
Suppose there is an extension module that exposes certain instances of
|
||||
the C++ <tt>std::vector</tt> template library such that it can be used
|
||||
from Python in the following manner:
|
||||
|
||||
<pre>
|
||||
import std_vector
|
||||
v = std_vector.double([1, 2, 3, 4])
|
||||
v.push_back(5)
|
||||
v.size()
|
||||
</pre>
|
||||
|
||||
Suppose the <tt>std_vector</tt> module is done well and reflects all
|
||||
C++ functions that are useful at the Python level, for all C++ built-in
|
||||
data types (<tt>std_vector.int</tt>, <tt>std_vector.long</tt>, etc.).
|
||||
|
||||
<p>
|
||||
Suppose further that there is statistic module with a C++ class that
|
||||
has constructors or member functions that use or return a
|
||||
<tt>std::vector</tt>. For example:
|
||||
|
||||
<pre>
|
||||
class xy {
|
||||
public:
|
||||
xy(const std::vector<double>& x, const std::vector<double>& y) : m_x(x), m_y(y) {}
|
||||
const std::vector<double>& x() const { return m_x; }
|
||||
const std::vector<double>& y() const { return m_y; }
|
||||
double correlation();
|
||||
private:
|
||||
std::vector<double> m_x;
|
||||
std::vector<double> m_y;
|
||||
}
|
||||
</pre>
|
||||
|
||||
What is more natural than reusing the <tt>std_vector</tt> extension
|
||||
module to expose these constructors or functions to Python?
|
||||
|
||||
<p>
|
||||
Unfortunately, what seems natural needs a little work in both the
|
||||
<tt>std_vector</tt> and the <tt>statistics</tt> module.
|
||||
|
||||
<p>
|
||||
In the <tt>std_vector</tt> extension module,
|
||||
<tt>std::vector<double></tt> is exposed to Python in the usual
|
||||
way with the <tt>class_builder<></tt> template. To also enable the
|
||||
automatic conversion of <tt>std::vector<double></tt> function
|
||||
arguments or return values in other Boost.Python C++ modules, the
|
||||
converters that convert a <tt>std::vector<double></tt> C++ object
|
||||
to a Python object and vice versa (i.e. the <tt>to_python()</tt> and
|
||||
<tt>from_python()</tt> template functions) have to be exported. For
|
||||
example:
|
||||
|
||||
<pre>
|
||||
#include <boost/python/cross_module.hpp>
|
||||
//...
|
||||
class_builder<std::vector<double> > v_double(std_vector_module, "double");
|
||||
export_converters(v_double);
|
||||
</pre>
|
||||
|
||||
In the extension module that wraps <tt>class xy</tt> we can now import
|
||||
these converters with the <tt>import_converters<></tt> template.
|
||||
For example:
|
||||
|
||||
<pre>
|
||||
#include <boost/python/cross_module.hpp>
|
||||
//...
|
||||
import_converters<std::vector<double> > v_double_converters("std_vector", "double");
|
||||
</pre>
|
||||
|
||||
That is all. All the attributes that are defined for
|
||||
<tt>std_vector.double</tt> in the <tt>std_vector</tt> Boost.Python
|
||||
module will be available for the returned objects of <tt>xy.x()</tt>
|
||||
and <tt>xy.y()</tt>. Similarly, the constructor for <tt>xy</tt> will
|
||||
accept objects that were created by the <tt>std_vector</tt>module.
|
||||
|
||||
<hr>
|
||||
<h2>Placement of <tt>import_converters<></tt> template instantiations</h2>
|
||||
|
||||
<tt>import_converts<></tt> can be viewed as a drop-in replacement
|
||||
for <tt>class_wrapper<></tt>, and the recommendations for the
|
||||
placement of <tt>class_wrapper<></tt> template instantiations
|
||||
also apply to to <tt>import_converts<></tt>. In particular, it is
|
||||
important that an instantiation of <tt>class_wrapper<></tt> is
|
||||
visible to any code which wraps a C++ function with a <tt>T</tt>,
|
||||
<tt>T*</tt>, const <tt>T&</tt>, etc. parameter or return value.
|
||||
Therefore you may want to group all <tt>class_wrapper<></tt> and
|
||||
<tt>import_converts<></tt> instantiations at the top of your
|
||||
module's init function, then <tt>def()</tt> the member functions later
|
||||
to avoid problems with inter-class dependencies.
|
||||
|
||||
<hr>
|
||||
<h2>Non-copyable types</h2>
|
||||
|
||||
<tt>export_converters()</tt> instantiates C++ template functions that
|
||||
invoke the copy constructor of the wrapped type. For a type that is
|
||||
non-copyable this will result in compile-time error messages. In such a
|
||||
case, <tt>export_converters_noncopyable()</tt> can be used to export
|
||||
the converters that do not involve the copy constructor of the wrapped
|
||||
type. For example:
|
||||
|
||||
<pre>
|
||||
class_builder<store> py_store(your_module, "store");
|
||||
export_converters_noncopyable(py_store);
|
||||
</pre>
|
||||
|
||||
The corresponding <tt>import_converters<></tt> statement does not
|
||||
need any special attention:
|
||||
|
||||
<pre>
|
||||
import_converters<store> py_store("noncopyable_export", "store");
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
<h2>Python module search path</h2>
|
||||
|
||||
The <tt>std_vector</tt> and <tt>statistics</tt> modules can now be used
|
||||
in the following way:
|
||||
|
||||
<pre>
|
||||
import std_vector
|
||||
import statistics
|
||||
x = std_vector.double([1, 2, 3, 4])
|
||||
y = std_vector.double([2, 4, 6, 8])
|
||||
xy = statistics.xy(x, y)
|
||||
xy.correlation()
|
||||
</pre>
|
||||
|
||||
In this example it is clear that Python has to be able to find both the
|
||||
<tt>std_vector</tt> and the <tt>statistics</tt> extension module. In
|
||||
other words, both extension modules need to be in the Python module
|
||||
search path (<tt>sys.path</tt>).
|
||||
|
||||
<p>
|
||||
The situation is not always this obvious. Suppose the
|
||||
<tt>statistics</tt> module has a <tt>random()</tt> function that
|
||||
returns a vector of random numbers with a given length:
|
||||
|
||||
<pre>
|
||||
import statistics
|
||||
x = statistics.random(5)
|
||||
y = statistics.random(5)
|
||||
xy = statistics.xy(x, y)
|
||||
xy.correlation()
|
||||
</pre>
|
||||
|
||||
A naive user will not easily anticipate that the <tt>std_vector</tt>
|
||||
module is used to pass the <tt>x</tt> and <tt>y</tt> vectors around. If
|
||||
the <tt>std_vector</tt> module is in the Python module search path,
|
||||
this form of ignorance is of no harm. On the contrary, we are glad
|
||||
that we do not have to bother the user with details like this.
|
||||
|
||||
<p>
|
||||
If the <tt>std_vector</tt> module is not in the Python module search
|
||||
path, a Python exception will be raised:
|
||||
|
||||
<pre>
|
||||
Traceback (innermost last):
|
||||
File "foo.py", line 2, in ?
|
||||
x = statistics.random(5)
|
||||
ImportError: No module named std_vector
|
||||
</pre>
|
||||
|
||||
As is the case with any system of a non-trivial complexity, it is
|
||||
important that the setup is consistent and complete.
|
||||
|
||||
<hr>
|
||||
<h2>Two-way module dependencies</h2>
|
||||
|
||||
Boost.Python supports two-way module dependencies. This is best
|
||||
illustrated by a simple example.
|
||||
|
||||
<p>
|
||||
Suppose there is a module <tt>ivect</tt> that implements vectors of
|
||||
integers, and a similar module <tt>dvect</tt> that implements vectors
|
||||
of doubles. We want to be able do convert an integer vector to a double
|
||||
vector and vice versa. For example:
|
||||
|
||||
<pre>
|
||||
import ivect
|
||||
iv = ivect.ivect((1,2,3,4,5))
|
||||
dv = iv.as_dvect()
|
||||
</pre>
|
||||
|
||||
The last expression will implicitly import the <tt>dvect</tt> module in
|
||||
order to enable the conversion of the C++ representation of
|
||||
<tt>dvect</tt> to a Python object. The analogous is possible for a
|
||||
<tt>dvect</tt>:
|
||||
|
||||
<pre>
|
||||
import dvect
|
||||
dv = dvect.dvect((1,2,3,4,5))
|
||||
iv = dv.as_ivect()
|
||||
</pre>
|
||||
|
||||
Now the <tt>ivect</tt> module is imported implicitly.
|
||||
|
||||
<p>
|
||||
Note that the two-way dependencies are possible because the
|
||||
dependencies are resolved only when needed. This is, the initialization
|
||||
of the <tt>ivect</tt> module does not rely on the <tt>dvect</tt>
|
||||
module, and vice versa. Only if <tt>as_dvect()</tt> or
|
||||
<tt>as_ivect()</tt> is actually invoked will the corresponding module
|
||||
be implicitly imported. This also means that, for example, the
|
||||
<tt>dvect</tt> module does not have to be available at all if
|
||||
<tt>as_dvect()</tt> is never used.
|
||||
|
||||
<hr>
|
||||
<h2>Clarification of compile-time and link-time dependencies</h2>
|
||||
|
||||
Boost.Python's support for resolving cross-module dependencies at
|
||||
runtime does not imply that compile-time dependencies are eliminated.
|
||||
For example, the statistics extension module in the example above will
|
||||
need to <tt>#include <vector></tt>. This is immediately obvious
|
||||
from the definition of <tt>class xy</tt>.
|
||||
|
||||
<p>
|
||||
If a library is wrapped that consists of both header files and compiled
|
||||
components (e.g. <tt>libdvect.a</tt>, <tt>dvect.lib</tt>, etc.), both
|
||||
the Boost.Python extension module with the
|
||||
<tt>export_converters()</tt> statement and the module with the
|
||||
<tt>import_converters<></tt> statement need to be linked against
|
||||
the object library. Ideally one would build a shared library (e.g.
|
||||
<tt>libdvect.so</tt>, <tt>dvect.dll</tt>, etc.). However, this
|
||||
introduces the issue of having to configure the search path for the
|
||||
dynamic loading correctly. For small libraries it is therefore often
|
||||
more convenient to ignore the fact that the object files are loaded
|
||||
into memory more than once.
|
||||
|
||||
<hr>
|
||||
<h2>Summary of motivation for cross-module support</h2>
|
||||
|
||||
The main purpose of Boost.Python's cross-module support is to allow for
|
||||
a modular system layout. With this support it is straightforward to
|
||||
reflect C++ code organization at the Python level. Without the
|
||||
cross-module support, a multi-purpose module like <tt>std_vector</tt>
|
||||
would be impractical because the entire wrapper code would somehow have
|
||||
to be duplicated in all extension modules that use it, making them
|
||||
harder to maintain and harder to build.
|
||||
|
||||
<p>
|
||||
Another motivation for the cross-module support is that two extension
|
||||
modules that wrap the same class cannot both be imported into Python.
|
||||
For example, if there are two modules <tt>A</tt> and <tt>B</tt> that
|
||||
both wrap a given <tt>class X</tt>, this will work:
|
||||
|
||||
<pre>
|
||||
import A
|
||||
x = A.X()
|
||||
</pre>
|
||||
|
||||
This will also work:
|
||||
|
||||
<pre>
|
||||
import B
|
||||
x = B.X()
|
||||
</pre>
|
||||
|
||||
However, this will fail:
|
||||
|
||||
<pre>
|
||||
import A
|
||||
import B
|
||||
python: /net/cci/rwgk/boost/boost/python/detail/extension_class.hpp:866:
|
||||
static void boost::python::detail::class_registry<X>::register_class(boost::python::detail::extension_class_base *):
|
||||
Assertion `static_class_object == 0' failed.
|
||||
Abort
|
||||
</pre>
|
||||
|
||||
A good solution is to wrap <tt>class X</tt> only once. Depending on the
|
||||
situation, this could be done by module <tt>A</tt> or <tt>B</tt>, or an
|
||||
additional small extension module that only wraps and exports
|
||||
<tt>class X</tt>.
|
||||
|
||||
<p>
|
||||
Finally, there can be important psychological or political reasons for
|
||||
using the cross-module support. If a group of classes is lumped
|
||||
together with many others in a huge module, the authors will have
|
||||
difficulties in being identified with their work. The situation is
|
||||
much more transparent if the work is represented by a module with a
|
||||
recognizable name. This is not just a question of strong egos, but also
|
||||
of getting credit and funding.
|
||||
|
||||
<hr>
|
||||
<h2>Why not use <tt>export_converters()</tt> universally?</h2>
|
||||
|
||||
There is some overhead associated with the Boost.Python cross-module
|
||||
support. Depending on the platform, the size of the code generated by
|
||||
<tt>export_converters()</tt> is roughly 10%-20% of that generated
|
||||
by <tt>class_builder<></tt>. For a large extension module with
|
||||
many wrapped classes, this could mean a significant difference.
|
||||
Therefore the general recommendation is to use
|
||||
<tt>export_converters()</tt> only for classes that are likely to
|
||||
be used as function arguments or return values in other modules.
|
||||
|
||||
<hr>
|
||||
© Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy,
|
||||
use, modify, sell and distribute this document is granted provided this
|
||||
copyright notice appears in all copies. This document is provided "as
|
||||
is" without express or implied warranty, and with no claim as to its
|
||||
suitability for any purpose.
|
||||
|
||||
<p>
|
||||
Updated: April 2001
|
||||
|
||||
</div>
|
||||
@@ -1,192 +0,0 @@
|
||||
Given a real Python class 'A', a wrapped C++ class 'B', and this definition:
|
||||
|
||||
class C(A, B):
|
||||
def __init__(self):
|
||||
B.__init__(self)
|
||||
self.x = 1
|
||||
...
|
||||
|
||||
c = C()
|
||||
|
||||
this diagram describes the internal structure of an instance of 'C', including
|
||||
its inheritance relationships. Note that ExtensionClass<B> is derived from
|
||||
Class<ExtensionInstance>, and is in fact identical for all intents and purposes.
|
||||
|
||||
MetaClass<ExtensionInstance>
|
||||
+---------+ +---------+
|
||||
types.ClassType: | | | |
|
||||
| | | |
|
||||
| | | |
|
||||
+---------+ +---------+
|
||||
^ ^ ^
|
||||
PyClassObject | ExtensionClass<B> | |
|
||||
A: +------------+ | B: +------------+ | |
|
||||
| ob_type -+-+ | ob_type -+-----+ |
|
||||
| | ()<--+- __bases__ | |
|
||||
| | | __dict__ -+->{...} |
|
||||
| | 'B'<-+- __name__ | |
|
||||
+------------+ +------------+ |
|
||||
^ ^ |
|
||||
| | |
|
||||
+-----+ +-------------+ |
|
||||
| | |
|
||||
| | Class<ExtensionInstance> |
|
||||
| | C: +------------+ |
|
||||
| | | ob_type -+------------+
|
||||
tuple:(*, *)<--+- __bases__ |
|
||||
| __dict__ -+->{__module__, <methods, etc.>}
|
||||
'C' <-+- __name__ |
|
||||
+------------+
|
||||
^ (in case of inheritance from more than one
|
||||
| extension class, this vector would contain
|
||||
+---------------+ a pointer to an instance holder for the data
|
||||
| of each corresponding C++ class)
|
||||
| ExtensionInstance
|
||||
| c: +---------------------+ std::vector<InstanceHolderBase>
|
||||
+----+- __class__ | +---+--
|
||||
| m_wrapped_objects -+->| * | ...
|
||||
{'x': 1}<-+- __dict__ | +-|-+--
|
||||
+---------------------+ | InstanceValueHolder<B>
|
||||
| +--------------------------------+
|
||||
+-->| (contains a C++ instance of B) |
|
||||
+--------------------------------+
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
In our inheritance test cases in extclass_demo.cpp/test_extclass.py, we have the
|
||||
following C++ inheritance hierarchy:
|
||||
|
||||
+-----+ +----+
|
||||
| A1 | | A2 |
|
||||
+-----+ +----+
|
||||
^ ^ ^ ^ ^
|
||||
| | | | |
|
||||
+-----+ | +---------+-----+
|
||||
| | | |
|
||||
| +---+----------+
|
||||
.......!...... | |
|
||||
: A_callback : +-+--+ +-+--+
|
||||
:............: | B1 | | B2 |
|
||||
+----+ +----+
|
||||
^
|
||||
|
|
||||
+-------+---------+
|
||||
| |
|
||||
+-+-+ ......!.......
|
||||
| C | : B_callback :
|
||||
+---+ :............:
|
||||
|
||||
|
||||
A_callback and B_callback are used as part of the wrapping mechanism but not
|
||||
represented in Python. C is also not represented in Python but is delivered
|
||||
there polymorphically through a smart pointer.
|
||||
|
||||
This is the data structure in Python.
|
||||
|
||||
ExtensionClass<A1>
|
||||
A1: +------------+
|
||||
()<--+- __bases__ |
|
||||
| __dict__ -+->{...}
|
||||
+------------+
|
||||
^
|
||||
| ExtensionInstance
|
||||
| a1: +---------------------+ vec InstanceValueHolder<A1,A_callback>
|
||||
+---------+- __class__ | +---+ +---------------------+
|
||||
| | m_wrapped_objects -+->| *-+-->| contains A_callback |
|
||||
| +---------------------+ +---+ +---------------------+
|
||||
|
|
||||
| ExtensionInstance
|
||||
| pa1_a1: +---------------------+ vec InstancePtrHolder<auto_ptr<A1>,A1>
|
||||
+---------+- __class__ | +---+ +---+
|
||||
| | m_wrapped_objects -+->| *-+-->| *-+-+ A1
|
||||
| +---------------------+ +---+ +---+ | +---+
|
||||
| +->| |
|
||||
| ExtensionInstance +---+
|
||||
| pb1_a1: +---------------------+ vec InstancePtrHolder<auto_ptr<A1>,A1>
|
||||
+---------+- __class__ | +---+ +---+
|
||||
| | m_wrapped_objects -+->| *-+-->| *-+-+ B1
|
||||
| +---------------------+ +---+ +---+ | +---+
|
||||
| +->| |
|
||||
| ExtensionInstance +---+
|
||||
| pb2_a1: +---------------------+ vec InstancePtrHolder<auto_ptr<A1>,A1>
|
||||
+---------+- __class__ | +---+ +---+
|
||||
| | m_wrapped_objects -+->| *-+-->| *-+-+ B2
|
||||
| +---------------------+ +---+ +---+ | +---+
|
||||
| +->| |
|
||||
| +---+
|
||||
| ExtensionClass<A1>
|
||||
| A2: +------------+
|
||||
| ()<--+- __bases__ |
|
||||
| | __dict__ -+->{...}
|
||||
| +------------+
|
||||
| ^
|
||||
| | ExtensionInstance
|
||||
| a2: | +---------------------+ vec InstanceValueHolder<A2>
|
||||
| +-+- __class__ | +---+ +-------------+
|
||||
| | | m_wrapped_objects -+->| *-+-->| contains A2 |
|
||||
| | +---------------------+ +---+ +-------------+
|
||||
| |
|
||||
| | ExtensionInstance
|
||||
| pa2_a2: | +---------------------+ vec InstancePtrHolder<auto_ptr<A2>,A2>
|
||||
| +-+- __class__ | +---+ +---+
|
||||
| | | m_wrapped_objects -+->| *-+-->| *-+-+ A2
|
||||
| | +---------------------+ +---+ +---+ | +---+
|
||||
| | +->| |
|
||||
| | ExtensionInstance +---+
|
||||
| pb1_a2: | +---------------------+ vec InstancePtrHolder<auto_ptr<A2>,A2>
|
||||
| +-+- __class__ | +---+ +---+
|
||||
| | | m_wrapped_objects -+->| *-+-->| *-+-+ B1
|
||||
| | +---------------------+ +---+ +---+ | +---+
|
||||
| | +->| |
|
||||
| | +---+
|
||||
| |
|
||||
| +---------------+------------------------------+
|
||||
| | |
|
||||
+------+-------------------------+-|----------------------------+ |
|
||||
| | | | |
|
||||
| Class<ExtensionInstance> | | ExtensionClass<B1> | | ExtensionClass<B1>
|
||||
| DA1: +------------+ | | B1: +------------+ | | B2: +------------+
|
||||
(*,)<---+- __bases__ | (*,*)<---+- __bases__ | (*,*)<---+- __bases__ |
|
||||
| __dict__ -+->{...} | __dict__ -+->{...} | __dict__ -+->{...}
|
||||
+------------+ +------------+ +------------+
|
||||
^ ^ ^
|
||||
| ExtensionInstance | |
|
||||
| da1: +---------------------+ | vec InstanceValueHolder<A1,A_callback>
|
||||
+-------+- __class__ | | +---+ +---------------------+ |
|
||||
| m_wrapped_objects -+--|-->| *-+-->| contains A_callback | |
|
||||
+---------------------+ | +---+ +---------------------+ |
|
||||
+--------------------------------------+ |
|
||||
| ExtensionInstance |
|
||||
b1: | +---------------------+ vec InstanceValueHolder<B1,B_callback> |
|
||||
+-+- __class__ | +---+ +---------------------+ |
|
||||
| | m_wrapped_objects -+->| *-+-->| contains B_callback | |
|
||||
| +---------------------+ +---+ +---------------------+ |
|
||||
| |
|
||||
| ExtensionInstance |
|
||||
pb1_b1: | +---------------------+ vec InstancePtrHolder<auto_ptr<B1>,B1> |
|
||||
+-+- __class__ | +---+ +---+ |
|
||||
| | m_wrapped_objects -+->| *-+-->| *-+-+ B1 |
|
||||
| +---------------------+ +---+ +---+ | +---+ |
|
||||
| +->| | |
|
||||
| ExtensionInstance +---+ |
|
||||
pc_b1: | +---------------------+ vec InstancePtrHolder<auto_ptr<B1>,B1> |
|
||||
+-+- __class__ | +---+ +---+ |
|
||||
| | m_wrapped_objects -+->| *-+-->| *-+-+ C |
|
||||
| +---------------------+ +---+ +---+ | +---+ |
|
||||
| +->| | |
|
||||
| +---+ |
|
||||
| |
|
||||
| Class<ExtensionInstance> +---------------------------------------+
|
||||
| DB1: +------------+ | ExtensionInstance
|
||||
(*,)<---+- __bases__ | a2: | +---------------------+ vec InstanceValueHolder<A2>
|
||||
| __dict__ -+->{...} +-+- __class__ | +---+ +-------------+
|
||||
+------------+ | m_wrapped_objects -+->| *-+-->| contains A2 |
|
||||
^ +---------------------+ +---+ +-------------+
|
||||
| ExtensionInstance
|
||||
db1: | +---------------------+ vec InstanceValueHolder<B1,B_callback>
|
||||
+-+- __class__ | +---+ +----------------------+
|
||||
| m_wrapped_objects -+-->| *-+-->| contains B1_callback |
|
||||
+---------------------+ +---+ +----------------------+
|
||||
120
doc/enums.html
@@ -1,120 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<title>
|
||||
Wrapping enums
|
||||
</title>
|
||||
<div>
|
||||
<h1>
|
||||
<img width="277" height="86" id="_x0000_i1025" align="center"
|
||||
src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)"><br>
|
||||
Wrapping enums
|
||||
</h1>
|
||||
|
||||
<p>Because there is in general no way to deduce that a value of arbitrary type T
|
||||
is an enumeration constant, the Boost Python Library cannot automatically
|
||||
convert enum values to and from Python. To handle this case, you need to decide
|
||||
how you want the enum to show up in Python (since Python doesn't have
|
||||
enums). Once you have done that, you can write some simple
|
||||
<code>from_python()</code> and <code>to_python()</code> functions.
|
||||
|
||||
<p>If you are satisfied with a Python int as a way to represent your enum
|
||||
values, we provide a shorthand for these functions. You just need to cause
|
||||
<code>boost::python::enum_as_int_converters<EnumType></code> to be
|
||||
instantiated, where
|
||||
<code>EnumType</code> is your enumerated type. There are two convenient ways to do this:
|
||||
|
||||
<ol>
|
||||
<li>Explicit instantiation:
|
||||
|
||||
<blockquote><pre>
|
||||
template class boost::python::enum_as_int_converters<my_enum>;
|
||||
</blockquote></pre>
|
||||
|
||||
Some buggy C++ implementations require a class to be instantiated in the same
|
||||
namespace in which it is defined. In that case, the simple incantation above becomes:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
...
|
||||
} // close my_namespace
|
||||
|
||||
// drop into namespace python and explicitly instantiate
|
||||
namespace boost { namespace python {
|
||||
template class enum_as_int_converters<my_enum_type>;
|
||||
}} // namespace boost::python
|
||||
|
||||
namespace my_namespace { // re-open my_namespace
|
||||
...
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<li>If you have such an implementation, you may find this technique more convenient
|
||||
<blockquote><pre>
|
||||
// instantiate as base class in any namespace
|
||||
struct EnumTypeConverters
|
||||
: boost::python::enum_as_int_converters<EnumType>
|
||||
{
|
||||
};
|
||||
</blockquote></pre>
|
||||
</ol>
|
||||
|
||||
<p>Either of the above is equivalent to the following declarations:
|
||||
<blockquote><pre>
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
|
||||
|
||||
MyEnumType from_python(PyObject* x, boost::python::type<MyEnumType>)
|
||||
{
|
||||
return static_cast<MyEnum>(
|
||||
from_python(x, boost::python::type<long>()));
|
||||
}
|
||||
|
||||
MyEnumType from_python(PyObject* x, boost::python::type<const MyEnumType&>)
|
||||
{
|
||||
return static_cast<MyEnum>(
|
||||
from_python(x, boost::python::type<long>()));
|
||||
}
|
||||
|
||||
PyObject* to_python(MyEnumType x)
|
||||
{
|
||||
return to_python(static_cast<long>(x));
|
||||
}
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
</pre></blockquote>
|
||||
|
||||
<p>This technique defines the conversions of
|
||||
<code>MyEnumType</code> in terms of the conversions for the built-in
|
||||
<code>long</code> type.
|
||||
|
||||
You may also want to add a bunch of lines like this to your module
|
||||
initialization. These bind the corresponding enum values to the appropriate
|
||||
names so they can be used from Python:
|
||||
|
||||
<blockquote><pre>
|
||||
mymodule.add(boost::python::to_python(enum_value_1), "enum_value_1");
|
||||
mymodule.add(boost::python::to_python(enum_value_2), "enum_value_2");
|
||||
...
|
||||
</pre></blockquote>
|
||||
|
||||
You can also add these to an extension class definition, if your enum happens to
|
||||
be local to a class and you want the analogous interface in Python:
|
||||
|
||||
<blockquote><pre>
|
||||
my_class_builder.add(boost::python::to_python(enum_value_1), "enum_value_1");
|
||||
my_class_builder.add(boost::python::to_python(enum_value_2), "enum_value_2");
|
||||
...
|
||||
</pre></blockquote>
|
||||
<p>
|
||||
Next: <a href="pointers.html">Pointers and Smart Pointers</a>
|
||||
Previous: <a href="building.html">Building an Extension Module</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided ``as
|
||||
is'' without express or implied warranty, and with no claim as to
|
||||
its suitability for any purpose.
|
||||
<p>
|
||||
Updated: Mar 6, 2001
|
||||
</div>
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<title>
|
||||
A Simple Example
|
||||
</title>
|
||||
<div>
|
||||
<h1>
|
||||
<img width="277" height="86" id="_x0000_i1025" src="../../../c++boost.gif" alt=
|
||||
"c++boost.gif (8819 bytes)">
|
||||
</h1>
|
||||
<h1>
|
||||
A Simple Example
|
||||
</h1>
|
||||
<p>
|
||||
Suppose we have the following C++ API which we want to expose in
|
||||
Python:
|
||||
<blockquote>
|
||||
<pre>
|
||||
#include <string>
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// A couple of simple C++ functions that we want to expose to Python.
|
||||
std::string greet() { return "hello, world"; }
|
||||
int square(int number) { return number * number; }
|
||||
}
|
||||
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>
|
||||
Here is the C++ code for a python module called <tt>getting_started1</tt>
|
||||
which exposes the API.
|
||||
<blockquote>
|
||||
<pre>
|
||||
#include <boost/python/class_builder.hpp>
|
||||
namespace python = boost::python;
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(getting_started1)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("getting_started1");
|
||||
|
||||
// Add regular functions to the module.
|
||||
this_module.def(greet, "greet");
|
||||
this_module.def(square, "square");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>
|
||||
That's it! If we build this shared library and put it on our <code>
|
||||
PYTHONPATH</code> we can now access our C++ functions from
|
||||
Python.
|
||||
<blockquote>
|
||||
<pre>
|
||||
>>> import getting_started1
|
||||
>>> print getting_started1.greet()
|
||||
hello, world
|
||||
>>> number = 11
|
||||
>>> print number, '*', number, '=', getting_started1.square(number)
|
||||
11 * 11 = 121
|
||||
</pre>
|
||||
<p>
|
||||
Next: <a href="exporting_classes.html">Exporting Classes</a>
|
||||
Previous: <a href="comparisons.html">Comparisons with other systems</a> Up:
|
||||
<a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is" without
|
||||
express or implied warranty, and with no claim as to its suitability
|
||||
for any purpose.
|
||||
<p>
|
||||
Updated: Mar 6, 2000
|
||||
</div>
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<title>
|
||||
Exporting Classes
|
||||
</title>
|
||||
<div>
|
||||
<h1>
|
||||
<img width="277" height="86" id="_x0000_i1025" src="../../../c++boost.gif" alt=
|
||||
"c++boost.gif (8819 bytes)">
|
||||
</h1>
|
||||
<h1>
|
||||
Exporting Classes
|
||||
</h1>
|
||||
<p>
|
||||
Now let's expose a C++ class to Python:
|
||||
|
||||
<blockquote><pre>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// A friendly class.
|
||||
class hello
|
||||
{
|
||||
public:
|
||||
hello(const std::string& country) { this->country = country; }
|
||||
std::string greet() const { return "Hello from " + country; }
|
||||
private:
|
||||
std::string country;
|
||||
};
|
||||
|
||||
// A function taking a hello object as an argument.
|
||||
std::string invite(const hello& w) {
|
||||
return w.greet() + "! Please come soon!";
|
||||
}
|
||||
}
|
||||
|
||||
</blockquote></pre> <p>
|
||||
To expose the class, we use a <tt>class_builder</tt> in addition to the
|
||||
<tt>module_builder</tt> from the previous example. Class member functions
|
||||
are exposed by using the <tt>def()</tt> member function on the
|
||||
<tt>class_builder</tt>:
|
||||
<blockquote><pre>
|
||||
#include <boost/python/class_builder.hpp>
|
||||
namespace python = boost::python;
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(getting_started2)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create an object representing this extension module.
|
||||
python::module_builder this_module("getting_started2");
|
||||
|
||||
// Create the Python type object for our extension class.
|
||||
python::class_builder<hello> hello_class(this_module, "hello");
|
||||
|
||||
// Add the __init__ function.
|
||||
hello_class.def(python::constructor<std::string>());
|
||||
// Add a regular member function.
|
||||
hello_class.def(&hello::greet, "greet");
|
||||
|
||||
// Add invite() as a regular function to the module.
|
||||
this_module.def(invite, "invite");
|
||||
|
||||
// Even better, invite() can also be made a member of hello_class!!!
|
||||
hello_class.def(invite, "invite");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
</blockquote></pre>
|
||||
<p>
|
||||
Now we can use the class normally from Python:
|
||||
|
||||
<blockquote><pre>
|
||||
>>> from getting_started2 import *
|
||||
>>> hi = hello('California')
|
||||
>>> hi.greet()
|
||||
'Hello from California'
|
||||
>>> invite(hi)
|
||||
'Hello from California! Please come soon!'
|
||||
>>> hi.invite()
|
||||
'Hello from California! Please come soon!'
|
||||
</blockquote></pre>
|
||||
|
||||
Notes:<ul>
|
||||
<li> We expose the class' constructor by calling <tt>def()</tt> on the
|
||||
<tt>class_builder</tt> with an argument whose type is
|
||||
<tt>constructor<</tt><i>params</i><tt>></tt>, where <i>params</i>
|
||||
matches the list of constructor argument types:
|
||||
|
||||
|
||||
<li>Regular member functions are defined by calling <tt>def()</tt> with a
|
||||
member function pointer and its Python name:
|
||||
|
||||
<li>Any function added to a class whose initial argument matches the class (or
|
||||
any base) will act like a member function in Python.
|
||||
</ul>
|
||||
<p>
|
||||
We can even make a subclass of <code>hello.world</code>:
|
||||
|
||||
<blockquote><pre>
|
||||
>>> class wordy(hello):
|
||||
... def greet(self):
|
||||
... return hello.greet(self) + ', where the weather is fine'
|
||||
...
|
||||
>>> hi2 = wordy('Florida')
|
||||
>>> hi2.greet()
|
||||
'Hello from Florida, where the weather is fine'
|
||||
>>> invite(hi2)
|
||||
'Hello from Florida! Please come soon!'
|
||||
</blockquote></pre>
|
||||
<p>
|
||||
Pretty cool! You can't do that with an ordinary Python extension type!
|
||||
|
||||
Of course, you may now have a slightly empty feeling in the pit of
|
||||
your little pythonic stomach. Perhaps you wanted to see the following
|
||||
<tt>wordy</tt> invitation:
|
||||
|
||||
<blockquote><pre>
|
||||
'Hello from Florida, where the weather is fine! Please come soon!'
|
||||
</blockquote></pre>
|
||||
|
||||
After all, <tt>invite</tt> calls <tt>hello::greet()</tt>, and you
|
||||
reimplemented that in your Python subclass, <tt>wordy</tt>. If so, <a
|
||||
href= "overriding.html">read on</a>...
|
||||
|
||||
<p>
|
||||
Next: <a href="overriding.html">Overridable virtual functions</a>
|
||||
Previous: <a href="example1.html">A Simple Example</a> Up:
|
||||
<a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is" without
|
||||
express or implied warranty, and with no claim as to its suitability
|
||||
for any purpose.
|
||||
<p>
|
||||
Updated: Mar 6, 2001
|
||||
</div>
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<title>
|
||||
A Brief Introduction to writing Python extension modules
|
||||
</title>
|
||||
<h1>
|
||||
<img src="../../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center"
|
||||
width="277" height="86">
|
||||
</h1>
|
||||
<h1>
|
||||
A Brief Introduction to writing Python extension modules
|
||||
</h1>
|
||||
<p>
|
||||
Interfacing any language to Python involves building a module which can
|
||||
be loaded by the Python interpreter, but which isn't written in Python.
|
||||
This is known as an <em>extension module</em>. Many of the <a href=
|
||||
"http://www.python.org/doc/current/lib/lib.html">built-in Python
|
||||
libraries</a> are constructed in 'C' this way; Python even supplies its
|
||||
<a href="http://www.python.org/doc/current/lib/types.html">fundamental
|
||||
types</a> using the same mechanism. An extension module can be statically
|
||||
linked with the Python interpreter, but it more commonly resides in a
|
||||
shared library or DLL.
|
||||
<p>
|
||||
As you can see from <a href=
|
||||
"http://www.python.org/doc/current/ext/ext.html"> The Python Extending
|
||||
and Embedding Tutorial</a>, writing an extension module normally means
|
||||
worrying about
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://www.python.org/doc/current/ext/refcounts.html">
|
||||
maintaining reference counts</a>
|
||||
<li>
|
||||
<a href="http://www.python.org/doc/current/ext/callingPython.html"> how
|
||||
to call back into Python</a>
|
||||
<li>
|
||||
<a href="http://www.python.org/doc/current/ext/parseTuple.html">
|
||||
function argument parsing and typechecking</a>
|
||||
</ul>
|
||||
This last item typically occupies a great deal of code in an extension
|
||||
module. Remember that Python is a completely dynamic language. A callable
|
||||
object receives its arguments in a tuple; it is up to that object to extract
|
||||
those arguments from the tuple, check their types, and raise appropriate
|
||||
exceptions. There are numerous other tedious details that need to be
|
||||
managed; too many to mention here. The Boost Python Library is designed to
|
||||
lift most of that burden.<br>
|
||||
<br>
|
||||
|
||||
<p>
|
||||
Another obstacle that most people run into eventually when extending
|
||||
Python is that there's no way to make a true Python class in an extension
|
||||
module. The typical solution is to create a new Python type in the
|
||||
extension module, and then write an additional module in 100% Python. The
|
||||
Python module defines a Python class which dispatches to an instance of
|
||||
the extension type, which it contains. This allows users to write
|
||||
subclasses of the class in the Python module, almost as though they were
|
||||
sublcassing the extension type. Aside from being tedious, it's not really
|
||||
the same as having a true class, because there's no way for the user to
|
||||
override a method of the extension type which is called from the
|
||||
extension module. Boost.Python solves this problem by taking advantage of <a
|
||||
href="http://www.python.org/doc/essays/metaclasses/">Python's metaclass
|
||||
feature</a> to provide objects which look, walk, and hiss almost exactly
|
||||
like regular Python classes. Boost.Python classes are actually cleaner than
|
||||
Python classes in some subtle ways; a more detailed discussion will
|
||||
follow (someday).</p>
|
||||
<p>Next: <a href="comparisons.html">Comparisons with Other Systems</a> Up: <a
|
||||
href="index.html">Top</a> </p>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is" without
|
||||
express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.</p>
|
||||
|
||||
304
doc/index.html
@@ -1,166 +1,184 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<title>
|
||||
The Boost Python Library (Boost.Python)
|
||||
</title>
|
||||
<h1>
|
||||
<img src="../../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277"
|
||||
align="center" height="86"><br>The Boost Python Library (Boost.Python)
|
||||
</h1>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
<p>
|
||||
Use the Boost Python Library to quickly and easily export a C++ library to <a
|
||||
href="http://www.python.org">Python</a> such that the Python interface is
|
||||
very similar to the C++ interface. It is designed to be minimally
|
||||
intrusive on your C++ design. In most cases, you should not have to alter
|
||||
your C++ classes in any way in order to use them with Boost.Python. The system
|
||||
<em>should</em> simply ``reflect'' your C++ classes and functions into
|
||||
Python. The major features of Boost.Python include support for:
|
||||
<ul>
|
||||
<li><a href="inheritance.html">Subclassing extension types in Python</a>
|
||||
<li><a href="overriding.html">Overriding virtual functions in Python</a>
|
||||
<li><a href="overloading.html">[Member] function Overloading</a>
|
||||
<li><a href="special.html#numeric_auto">Automatic wrapping of numeric operators</a>
|
||||
</ul>
|
||||
among others.
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
|
||||
<title>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="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
|
||||
<h2 align="center">Index</h2>
|
||||
</td>
|
||||
|
||||
|
||||
<h2>Supported Platforms</h2>
|
||||
<p>Boost.Python is known to have been tested in the following configurations:
|
||||
<td align="right">
|
||||
|
||||
<ul>
|
||||
<li>Against Python 2.0 using the following compiler/library combinations:
|
||||
<ul>
|
||||
<li><a
|
||||
href="http://msdn.microsoft.com/vstudio/sp/vs6sp4/dnldoverview.asp">MSVC++6sp4</a>
|
||||
with the native library.
|
||||
<form method="get" action="http://www.google.com/custom">
|
||||
<p>
|
||||
<span id= "search-choice">
|
||||
Search
|
||||
<select name="hq" id="hq">
|
||||
<option label="All Documentation" value=
|
||||
"site:www.boost.org inurl:www.boost.org/libs/python/doc">
|
||||
All Documentation
|
||||
</option>
|
||||
<option label="Tutorial" value=
|
||||
"site:www.boost.org inurl:www.boost.org/libs/python/doc/tutorial">
|
||||
Tutorial
|
||||
</option>
|
||||
<option label="Reference" value=
|
||||
"site:www.boost.org inurl:www.boost.org/libs/python/doc/v2">
|
||||
Reference
|
||||
</option>
|
||||
</select>
|
||||
<br>
|
||||
</span>
|
||||
|
||||
<li>An upcoming release of <a
|
||||
href="http://www.metrowerks.com/products/windows/">Metrowerks
|
||||
CodeWarrior Pro6 for Windows</a> with the native library (the first
|
||||
release has a bug that's fatal to Boost.Python)
|
||||
<span id="search-text">
|
||||
<input type="text" name="q" id="q" size="31" maxlength="255" alt="Search Text" />
|
||||
</span>
|
||||
|
||||
<li><a
|
||||
href="http://developer.intel.com/software/products/compilers/c50/">Intel
|
||||
C++ 5.0</a>. Compilation succeeds, but tests <font
|
||||
color="#FF0000"><b>FAILED at runtime</b></font> due to a bug in its
|
||||
exception-handling implementation.
|
||||
</ul>
|
||||
<br>
|
||||
<span id= "google">
|
||||
<a href= "http://www.google.com/search">
|
||||
<img src="../../../more/google_logo_25wht.gif" alt="Google" border="0" /></a>Powered
|
||||
</span>
|
||||
|
||||
<li>Against Python 1.5.2 using the following compiler/library:
|
||||
<span id="go">
|
||||
<input type="image" name="search" src="../../../more/space.gif" alt="Search" id="search-button" />
|
||||
</span>
|
||||
|
||||
<ul>
|
||||
<li><a
|
||||
href="http://msdn.microsoft.com/vstudio/sp/vs6sp4/dnldoverview.asp">MSVC++6sp4</a>
|
||||
<br>
|
||||
<input type="hidden" name="cof" value= "LW:277;L:http://www.boost.org/boost.png;LH:86;AH:center;GL:0;S:http://www.boost.org;AWFID:9b83d16ce652ed5a;" />
|
||||
<input type="hidden" name="sa" value= "Google Search" />
|
||||
<input type="hidden" name= "domains" value= "www.boost.org;mail.python.org" /></p>
|
||||
</form>
|
||||
|
||||
<li><a
|
||||
href="http://msdn.microsoft.com/vstudio/sp/vs6sp4/dnldoverview.asp">MSVC++6sp4</a>/<a
|
||||
href="http://www.stlport.org">STLport 4.0</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<li><a href="http://gcc.gnu.org/">GCC 2.95.2</a> [by <a href="mailto:koethe@informatik.uni-hamburg.de">Ullrich
|
||||
Koethe</a>]
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<li><a href="http://gcc.gnu.org/">GCC 2.95.2</a>/<a href="http://www.stlport.org">STLport 4.0</a>
|
||||
|
||||
<li>Compaq C++ V6.2-024 for Digital UNIX V5.0 Rev. 910 (an <a
|
||||
href="http://www.edg.com/">EDG</a>-based compiler) with <a
|
||||
href="http://www.stlport.org/beta.html">STLport-4.1b3</a> [by <a
|
||||
href="mailto:rwgk@cci.lbl.gov">Ralf W. Grosse-Kunstleve</a>]
|
||||
<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:
|
||||
|
||||
<li>An upcoming release of <a href="http://www.metrowerks.com/products/windows/">Metrowerks CodeWarrior
|
||||
Pro6 for Windows</a> (the first release has a bug that's fatal to Boost.Python)
|
||||
</ul>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>References and Pointers</li>
|
||||
|
||||
<h2>Credits</h2>
|
||||
<ul>
|
||||
<li><a href="../../../people/dave_abrahams.htm">David Abrahams</a> originated
|
||||
and wrote most of the library, and continues to coordinate development.
|
||||
<li>Globally Registered Type Coercions</li>
|
||||
|
||||
<li><a href="mailto:koethe@informatik.uni-hamburg.de">Ullrich Koethe</a>
|
||||
had independently developed a similar system. When he discovered Boost.Python,
|
||||
he generously contributed countless hours of coding and much insight into
|
||||
improving it. He is responsible for an early version of the support for <a
|
||||
href="overloading.html">function overloading</a> and wrote the support for
|
||||
<a href="inheritance.html#implicit_conversion">reflecting C++ inheritance
|
||||
relationships</a>. He has helped to improve error-reporting from both
|
||||
Python and C++, and has designed an extremely easy-to-use way of
|
||||
exposing <a href="special.html#numeric">numeric operators</a>, including
|
||||
a way to avoid explicit coercion by means of overloading.
|
||||
<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">
|
||||
<dt><a href="tutorial/index.html">Tutorial Introduction</a></dt>
|
||||
|
||||
<dt><a href="building.html">Building and Testing</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/platforms.html">Known Working Platforms and
|
||||
Compilers</a></dt>
|
||||
|
||||
<dt><a href="v2/definitions.html">Definitions</a></dt>
|
||||
|
||||
<dt><a href="projects.html">Projects using Boost.Python</a></dt>
|
||||
|
||||
<dt><a href="support.html">Support Resources</a></dt>
|
||||
|
||||
<dt><a href="v2/faq.html">Frequently Asked Questions (FAQs)</a></dt>
|
||||
|
||||
<li><a href="http://cci.lbl.gov/staff/ralf_grosse-kunstleve.html">Ralf W.
|
||||
Grosse-Kunstleve</a> contributed <a href="pickle.html">pickle support</a>
|
||||
and numerous other small improvements. He's working on a way to allow
|
||||
types exported by multiple modules to interact.
|
||||
<dt><a href="http://www.language-binding.net/pyplusplus/pyplusplus.html">Py++ Boost.Python code generator</a></dt>
|
||||
|
||||
<li>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.
|
||||
<dt><a href="../pyste/index.html">Pyste Boost.Python code generator (no longer maintained)</a></dt>
|
||||
|
||||
<li>The development of Boost.Python wouldn't have been possible without
|
||||
the generous support of <a href="http://www.dragonsys.com/">Dragon
|
||||
Systems/Lernout and Hauspie, Inc</a> who supported its development as an
|
||||
open-source project.
|
||||
</ul>
|
||||
<dt><a href="internals.html">Internals Documentation</a></dt>
|
||||
|
||||
<h2>Table of Contents</h2>
|
||||
|
||||
<ol>
|
||||
<li><a href="extending.html">A Brief Introduction to writing Python
|
||||
extension modules</a>
|
||||
|
||||
<li><a href="comparisons.html">Comparisons between Boost.Python and other
|
||||
systems for extending Python</a>
|
||||
|
||||
<li><a href="example1.html">A Simple Example</a>
|
||||
|
||||
<li><a href="exporting_classes.html">Exporting Classes</a>
|
||||
|
||||
<li><a href="overriding.html">Overridable Virtual Functions</a>
|
||||
|
||||
<li><a href="overloading.html">Function Overloading</a>
|
||||
|
||||
<li><a href="inheritance.html">Inheritance</a>
|
||||
|
||||
<li><a href="special.html">Special Method and Operator Support</a>
|
||||
|
||||
<li><a href="under-the-hood.html">A Peek Under the Hood</a>
|
||||
|
||||
<li><a href="building.html">Building an Extension Module</a>
|
||||
|
||||
<li><a href="pickle.html">Pickle Support</a>
|
||||
|
||||
<li><a href="cross_module.html">Cross-Extension-Module Dependencies</a>
|
||||
|
||||
<li><a href="enums.html">Wrapping Enums</a>
|
||||
|
||||
<li><a href="pointers.html">Pointers and Smart Pointers</a>
|
||||
|
||||
<li><a href="data_structures.txt">Internal Data Structures</a>
|
||||
|
||||
</ol>
|
||||
<dt><a href="news.html">News/Change Log</a></dt>
|
||||
|
||||
<p>
|
||||
Documentation is a major ongoing project; assistance is greatly
|
||||
appreciated! In the meantime, useful examples of every Boost.Python feature should
|
||||
be evident in the regression test files <code>test/comprehensive.[<a
|
||||
href="../test/comprehensive.py">py</a>/<a
|
||||
href="../test/comprehensive.hpp">hpp</a>/<a
|
||||
href="../test/comprehensive.cpp">cpp</a>]</code>
|
||||
<dt><a href="../todo.html">TODO list</a></dt>
|
||||
|
||||
<p>
|
||||
Questions should be directed to <a href=
|
||||
"http://www.yahoogroups.com/list/boost">the boost mailing list</a>.
|
||||
<dt><a href="v2/progress_reports.html">LLNL Progress Reports</a></dt>
|
||||
|
||||
<p>
|
||||
© Copyright David Abrahams 2001. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided ``as is'' without
|
||||
express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.
|
||||
<p>
|
||||
Updated: Mar 6, 2001
|
||||
<dt><a href="v2/acknowledgments.html">Acknowledgments</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2>Articles</h2>
|
||||
|
||||
"<a href="PyConDC_2003/bpl.html">Building Hybrid
|
||||
Systems With Boost Python</a>", 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 -->
|
||||
26 August, 2003
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002-2003.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<title>
|
||||
Inheritance
|
||||
</title>
|
||||
<div>
|
||||
<h1>
|
||||
<img width="277" height="86" id="_x0000_i1025" align="center"
|
||||
src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">Inheritance
|
||||
</h1>
|
||||
|
||||
<h2>Inheritance in Python</h2>
|
||||
|
||||
<p>
|
||||
Boost.Python extension classes support single and multiple-inheritance in
|
||||
Python, just like regular Python classes. You can arbitrarily mix
|
||||
built-in Python classes with extension classes in a derived class'
|
||||
tuple of bases. Whenever a Boost.Python extension class is among the bases for a
|
||||
new class in Python, the result is an extension class:
|
||||
<blockquote>
|
||||
<pre>
|
||||
>>> class MyPythonClass:
|
||||
... def f(): return 'MyPythonClass.f()'
|
||||
...
|
||||
>>> import my_extension_module
|
||||
>>> class Derived(my_extension_module.MyExtensionClass, MyPythonClass):
|
||||
... '''This is an extension class'''
|
||||
... pass
|
||||
...
|
||||
>>> x = Derived()
|
||||
>>> x.f()
|
||||
'MyPythonClass.f()'
|
||||
>>> x.g()
|
||||
'MyExtensionClass.g()'
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h2><a name="implicit_conversion">Reflecting C++ Inheritance Relationships</a></h2>
|
||||
<p>
|
||||
Boost.Python also allows us to represent C++ inheritance relationships so that
|
||||
wrapped derived classes may be passed where values, pointers, or
|
||||
references to a base class are expected as arguments. The
|
||||
<code>declare_base</code> member function of
|
||||
<code>class_builder<></code> is used to establish the relationship
|
||||
between base and derived classes:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
#include <memory> // for std::auto_ptr<>
|
||||
|
||||
struct Base {
|
||||
virtual ~Base() {}
|
||||
virtual const char* name() const { return "Base"; }
|
||||
};
|
||||
|
||||
struct Derived : Base {
|
||||
Derived() : x(-1) {}
|
||||
virtual const char* name() const { return "Derived"; }
|
||||
int x;
|
||||
};
|
||||
|
||||
std::auto_ptr<Base> derived_as_base() {
|
||||
return std::auto_ptr<Base>(new Derived);
|
||||
}
|
||||
|
||||
const char* get_name(const Base& b) {
|
||||
return b.name();
|
||||
}
|
||||
|
||||
int get_derived_x(const Derived& d) {
|
||||
return d.x;
|
||||
}
|
||||
<hr>
|
||||
#include <boost/python/class_builder.hpp>
|
||||
|
||||
// namespace alias for code brevity
|
||||
namespace python = boost::python;
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(my_module)
|
||||
{
|
||||
try
|
||||
{
|
||||
python::module_builder my_module("my_module");
|
||||
|
||||
python::class_builder<Base> base_class(my_module, "Base");
|
||||
base_class.def(python::constructor<void>());
|
||||
|
||||
python::class_builder<Derived> derived_class(my_module, "Derived");
|
||||
derived_class.def(python::constructor<void>());
|
||||
<b>// Establish the inheritance relationship between Base and Derived
|
||||
derived_class.declare_base(base_class);</b>
|
||||
|
||||
my_module.def(derived_as_base, "derived_as_base");
|
||||
my_module.def(get_name, "get_name");
|
||||
my_module.def(get_derived_x, "get_derived_x");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
Then, in Python:
|
||||
<blockquote>
|
||||
<pre>
|
||||
>>> from my_module import *
|
||||
>>> base = Base()
|
||||
>>> derived = Derived()
|
||||
>>> get_name(base)
|
||||
'Base'
|
||||
</pre>
|
||||
</blockquote>
|
||||
<i>objects of wrapped class Derived may be passed where Base is expected</i>
|
||||
<blockquote>
|
||||
<pre>
|
||||
>>> get_name(derived)
|
||||
'Derived'
|
||||
</pre>
|
||||
</blockquote>
|
||||
<i>objects of wrapped class Derived can be passed where Derived is
|
||||
expected but where type information has been lost.</i>
|
||||
<blockquote>
|
||||
<pre>
|
||||
>>> get_derived_x(derived_as_base())
|
||||
-1
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h2>Inheritance Without Virtual Functions</h2>
|
||||
|
||||
<p>
|
||||
If for some reason your base class has no virtual functions but you still want
|
||||
to represent the inheritance relationship between base and derived classes,
|
||||
pass the special symbol <code>boost::python::without_downcast</code> as the 2nd parameter
|
||||
to <code>declare_base</code>:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
struct Base2 {};
|
||||
struct Derived2 { int f(); };
|
||||
<hr>
|
||||
...
|
||||
python::class_builder<Base> base2_class(my_module, "Base2");
|
||||
base2_class.def(python::constructor<void>());
|
||||
|
||||
python::class_builder<Derived2> derived2_class(my_module, "Derived2");
|
||||
derived2_class.def(python::constructor<void>());
|
||||
derived_class.declare_base(base_class, <b>python::without_downcast</b>);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>This approach will allow <code>Derived2</code> objects to be passed where
|
||||
<code>Base2</code> is expected, but does not attempt to implicitly convert (downcast)
|
||||
smart-pointers to <code>Base2</code> into <code>Derived2</code> pointers,
|
||||
references, or values.
|
||||
|
||||
<p>
|
||||
Next: <a href="special.html">Special Method and Operator Support</a>
|
||||
Previous: <a href="overloading.html">Function Overloading</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is" without
|
||||
express or implied warranty, and with no claim as to its suitability
|
||||
for any purpose.
|
||||
<p>
|
||||
Updated: Nov 26, 2000
|
||||
</div>
|
||||
|
||||
186
doc/internals.html
Normal 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="../../../boost.png" /></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_<boring>("boring")
|
||||
;
|
||||
</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 "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.</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">
|
||||
>>> 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<boring,</span> <span class="pre">non_copyable,</span>
|
||||
<span class="pre">...></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<boring</span> <span class="pre">...>(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<boring></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<></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 ->
|
||||
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<>(...)</span></tt>, <tt class="literal"><span class="pre">call_method<>(...)</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, "return value" conversion
|
||||
(for Python->C++ calls) and "argument" conversion (for
|
||||
C++->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 "default" 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 "return value"
|
||||
and "argument" 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
Normal file
@@ -0,0 +1,182 @@
|
||||
===================================
|
||||
Boost.Python_ Internals |(logo)|__
|
||||
===================================
|
||||
|
||||
.. |(logo)| image:: ../../../boost.png
|
||||
: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.
|
||||
|
||||
371
doc/news.html
Normal file
@@ -0,0 +1,371 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Cygwin (vers 1st September 2004), 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 - 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="../../../boost.png" 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>Current SVN</dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li>Python 3 support:</li>
|
||||
<ul>
|
||||
<li>All the current Boost.Python test cases passed. Extension modules using
|
||||
Boost.Python expected to support Python 3 smoothly.</li>
|
||||
<li>Introduced <code>object.contains</code> where <code>x.contains(y)</code>
|
||||
is equivalent to Python code <code>y in x</code>.
|
||||
Now <code>dict.has_key</code> is just a wrapper of <code>object.contains</code>.
|
||||
</li>
|
||||
<li>When building against Python 3, <code>str.decode</code> will be removed.</li>
|
||||
<li>When building against Python 3, the original signature of <code>list.sort</code>, which is:
|
||||
<pre>void sort(object_cref cmpfunc);</pre>
|
||||
will change to:
|
||||
<pre>void sort(args_proxy const &args, kwds_proxy const &kwds);</pre>
|
||||
|
||||
This is because in Python 3 <code>list.sort</code> requires all its arguments be keyword arguments.
|
||||
So you should call it like this:
|
||||
<pre>x.sort(*tuple(), **dict(make_tuple(make_tuple("reverse", true))));</pre>
|
||||
|
||||
</li>
|
||||
<li>According to <a href="http://www.python.org/dev/peps/pep-3123/">PEP 3123</a>,
|
||||
when building Boost.Python against Python older than 2.6, the following macros will
|
||||
be defined in Boost.Python header:
|
||||
<pre>
|
||||
# define Py_TYPE(o) (((PyObject*)(o))->ob_type)
|
||||
# define Py_REFCNT(o) (((PyObject*)(o))->ob_refcnt)
|
||||
# define Py_SIZE(o) (((PyVarObject*)(o))->ob_size)</pre>
|
||||
So extension writers can use these macro directly, to make code clean and compatible with Python 3.
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt>1.39.0 Release</dt>
|
||||
|
||||
<dd>
|
||||
<ul>
|
||||
<li>Pythonic signatures are now automatically appended to the
|
||||
docstrings.
|
||||
|
||||
<li>Use <a href="v2/docstring_options.html"
|
||||
><code>docstring_options.hpp</code></a> header
|
||||
control the content of docstrings.
|
||||
|
||||
<li>This new feature increases the size of the modules by about 14%.
|
||||
If this is not acceptable it can be turned off by defining the macro
|
||||
BOOST_PYTHON_NO_PY_SIGNATURES. Modules compiled with and without the macro
|
||||
defined are compatible.
|
||||
</li>
|
||||
<li> If BOOST_PYTHON_NO_PY_SIGNATURES is undefined, this version defines the
|
||||
macro BOOST_PYTHON_SUPPORTS_PY_SIGNATURES. This allows writing code that will compile
|
||||
with older version of Boost.Python (see <a href="v2/pytype_function.html#examples">here</a>).
|
||||
</li>
|
||||
<li>By defining BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE, and at a cost
|
||||
of another 14% size increase, proper pythonic type is generated for the "self"
|
||||
parameter of the __init__ methods.
|
||||
</li>
|
||||
|
||||
<li> To support this new feature changes were made to the
|
||||
<a href="v2/to_python_converter.html"><code>to_python_converter.hpp</code></a>,
|
||||
<a href="v2/default_call_policies.html"><code>default_call_policies</code></a>,
|
||||
<a href="v2/ResultConverter.html"><code>ResultConverter</code></a>,
|
||||
<a href="v2/CallPolicies.html"><code>CallPolicies</code></a> and some others.
|
||||
Efforts were made not to have interface breaking changes.
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt>12 May 2007 - 1.34.0 release</dt>
|
||||
|
||||
<dd>
|
||||
<ul>
|
||||
<li>C++ signatures are now automatically appended to the
|
||||
docstrings.
|
||||
|
||||
<li>New <a href="v2/docstring_options.html"
|
||||
><code>docstring_options.hpp</code></a> header to
|
||||
control the content of docstrings.
|
||||
|
||||
<li>Support for converting <code>void*</code> to/from python,
|
||||
with <code><a
|
||||
href="v2/opaque.html">opaque_pointer_converter</a></code>
|
||||
as the return value policy. Thanks to Niall Douglas for the
|
||||
initial patch.
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt>19 October 2005 - 1.33.1 release</dt>
|
||||
|
||||
<dd>
|
||||
<ul>
|
||||
<li><code>wrapper<T></code> can now be used as expected with a
|
||||
held type of <i>some-smart-pointer</i><code><T></code></li>
|
||||
|
||||
<li>The build now assumes Python 2.4 by default, rather than 2.2</li>
|
||||
|
||||
<li>Support Python that's built without Unicode support</li>
|
||||
|
||||
<li>Support for wrapping classes with overloaded address-of
|
||||
(<code>&</code>) operators</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt>14 August 2005 - 1.33 release</dt>
|
||||
|
||||
<dd>
|
||||
<ul>
|
||||
<li>Support for docstrings on nonstatic properties.</li>
|
||||
|
||||
<li>We now export the client-provided docstrings for
|
||||
<code>init<optional<> ></code> and
|
||||
<i>XXX</i><code>_FUNCTION_OVERLOADS()</code> for only the last
|
||||
overload.</li>
|
||||
|
||||
<li>Fixed some support for Embedded VC++ 4</li>
|
||||
|
||||
<li>Better support for rvalue from-python conversions of shared_ptr:
|
||||
always return a pointer that holds the owning python object *unless*
|
||||
the python object contains a NULL shared_ptr holder of the right
|
||||
type.</li>
|
||||
|
||||
<li>Support for exposing <code>vector<T*></code> with the
|
||||
indexing suite.</li>
|
||||
|
||||
<li>Support for GCC-3.3 on MacOS.</li>
|
||||
|
||||
<li>updated visual studio project build file to include two new files
|
||||
(slice.cpp and wrapper.cpp)</li>
|
||||
|
||||
<li>Added search feature to the index page.</li>
|
||||
|
||||
<li>Numerous fixes to the tutorial</li>
|
||||
|
||||
<li>Numerous workarounds for MSVC 6 and 7, GCC 2.96, and EDG
|
||||
2.45</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt>11 March 2005</dt>
|
||||
|
||||
<dd>
|
||||
<ul>
|
||||
<li>Added a hack that will fool PyDoc into working with Boost.Python,
|
||||
thanks to Nick Rasmussen</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt>19 November 2004 - 1.32 release</dt>
|
||||
|
||||
<dd>
|
||||
<ul>
|
||||
<li>Updated to use the Boost Software License.</li>
|
||||
|
||||
<li>A new, <a href=
|
||||
"tutorial/doc/html/python/exposing.html#python.class_virtual_functions">
|
||||
better method of wrapping classes with virtual functions</a> has been
|
||||
implemented.</li>
|
||||
|
||||
<li>Support for upcoming GCC symbol export control features have been
|
||||
folded in, thanks to Niall Douglas.</li>
|
||||
|
||||
<li>Improved support for <code>std::auto_ptr</code>-like types.</li>
|
||||
|
||||
<li>The Visual C++ bug that makes top-level <i>cv-qualification</i>
|
||||
of function parameter types part of the function type has been worked
|
||||
around.</li>
|
||||
|
||||
<li>Components used by other libraries have been moved out of
|
||||
<code>python/detail</code> and into <code>boost/detail</code> to
|
||||
improve dependency relationships.</li>
|
||||
|
||||
<li>Miscellaneous bug fixes and compiler workarounds.</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt>8 Sept 2004</dt>
|
||||
|
||||
<dd>Support for Python's Bool type, thanks to <a href=
|
||||
"mailto:dholth-at-fastmail.fm">Daniel Holth</a>.</dd>
|
||||
|
||||
<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> => 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>
|
||||
>>> import test
|
||||
>>> f(0, z = "bar")
|
||||
>>> 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ßauge</a> has contributed <a href=
|
||||
"v2/opaque.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<X></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<></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 -->
|
||||
19 November 2004
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
|
||||
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002-2003.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,155 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<title>
|
||||
Function Overloading
|
||||
</title>
|
||||
<div>
|
||||
<h1>
|
||||
<img width="277" height="86" id="_x0000_i1025" align="center"
|
||||
src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">Function Overloading
|
||||
</h1>
|
||||
|
||||
<h2>An Example</h2>
|
||||
<p>
|
||||
To expose overloaded functions in Python, simply <code>def()</code> each
|
||||
one with the same Python name:
|
||||
<blockquote>
|
||||
<pre>
|
||||
inline int f1() { return 3; }
|
||||
inline int f2(int x) { return x + 1; }
|
||||
|
||||
class X {
|
||||
public:
|
||||
X() : m_value(0) {}
|
||||
X(int n) : m_value(n) {}
|
||||
int value() const { return m_value; }
|
||||
void value(int v) { m_value = v; }
|
||||
private:
|
||||
int m_value;
|
||||
};
|
||||
...
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(overload_demo)
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::python::module_builder overload_demo("overload_demo");
|
||||
// Overloaded functions at module scope
|
||||
overload_demo.def(f1, "f");
|
||||
overload_demo.def(f2, "f");
|
||||
|
||||
boost::python::class_builder<X> x_class(overload_demo, "X");
|
||||
// Overloaded constructors
|
||||
x_class.def(boost::python::constructor<>());
|
||||
x_class.def(boost::python::constructor<int>());
|
||||
|
||||
// Overloaded member functions
|
||||
x_class.def((int (X::*)() const)&X::value, "value");
|
||||
x_class.def((void (X::*)(int))&X::value, "value");
|
||||
...
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
Now in Python:
|
||||
<blockquote>
|
||||
<pre>
|
||||
>>> from overload_demo import *
|
||||
>>> x0 = X()
|
||||
>>> x1 = X(1)
|
||||
>>> x0.value()
|
||||
0
|
||||
>>> x1.value()
|
||||
1
|
||||
>>> x0.value(3)
|
||||
>>> x0.value()
|
||||
3
|
||||
>>> X('hello')
|
||||
TypeError: No overloaded functions match (X, string). Candidates are:
|
||||
void (*)()
|
||||
void (*)(int)
|
||||
>>> f()
|
||||
3
|
||||
>>> f(4)
|
||||
5
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h2>Discussion</h2>
|
||||
<p>
|
||||
Notice that overloading in the Python module was produced three ways:<ol>
|
||||
<li>by combining the non-overloaded C++ functions <code>int f1()</code>
|
||||
and <code>int f2(int)</code> and exposing them as <code>f</code> in Python.
|
||||
<li>by exposing the overloaded constructors of <code>class X</code>
|
||||
<li>by exposing the overloaded member functions <code>X::value</code>.
|
||||
</ol>
|
||||
<p>
|
||||
Techniques 1. and 3. above are really alternatives. In case 3, you need
|
||||
to form a pointer to each of the overloaded functions. The casting
|
||||
syntax shown above is one way to do that in C++. Case 1 does not require
|
||||
complicated-looking casts, but may not be viable if you can't change
|
||||
your C++ interface. N.B. There's really nothing unsafe about casting an
|
||||
overloaded (member) function address this way: the compiler won't let
|
||||
you write it at all unless you get it right.
|
||||
|
||||
<h2>An Alternative to Casting</h2>
|
||||
<p>
|
||||
This approach is not neccessarily better, but may be preferable for some
|
||||
people who have trouble writing out the types of (member) function
|
||||
pointers or simply prefer to avoid all casts as a matter of principle:
|
||||
<blockquote>
|
||||
<pre>
|
||||
// Forwarding functions for X::value
|
||||
inline void set_x_value(X& self, int v) { self.value(v); }
|
||||
inline int get_x_value(X& self) { return self.value(); }
|
||||
...
|
||||
// Overloaded member functions
|
||||
x_class.def(set_x_value, "value");
|
||||
x_class.def(get_x_value, "value");
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>Here we are taking advantage of the ability to expose C++ functions at
|
||||
namespace scope as Python member functions.
|
||||
|
||||
<h2>Overload Resolution</h2>
|
||||
<p>
|
||||
The function overload resolution mechanism works as follows:
|
||||
|
||||
<ul>
|
||||
|
||||
<li>Attribute lookup for extension classes proceeds in <a
|
||||
href="http://www.python.org/doc/current/tut/node11.html#SECTION0011510000000000000000">the
|
||||
usual Python way</a> using a depth-first, left-to-right search. When a
|
||||
class is found which has a matching attribute, only functions overloaded
|
||||
in the context of that class are candidates for overload resolution. In
|
||||
this sense, overload resolution mirrors the C++ mechanism, where a name
|
||||
in a derived class ``hides'' all functions with the same name from a base
|
||||
class.
|
||||
<p>
|
||||
|
||||
<li>Within a name-space context (extension class or module), overloaded
|
||||
functions are tried in the same order they were
|
||||
<code>def()</code>ed. The first function whose signature can be made to
|
||||
match each argument passed is the one which is ultimately called.
|
||||
This means in particular that you cannot overload the same function on
|
||||
both ``<code>int</code>'' and ``<code>float</code>'' because Python
|
||||
automatically converts either of the two types into the other one.
|
||||
If the ``<code>float</code>'' overload is found first, it is used
|
||||
also used for arguments of type ``<code>int</code>'' as well, and the
|
||||
``<code>int</code>'' version of the function is never invoked.
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Next: <a href="inheritance.html">Inheritance</a>
|
||||
Previous: <a href="overriding.html">Overridable Virtual Functions</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2001. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided ``as
|
||||
is'' without express or implied warranty, and with no claim as to
|
||||
its suitability for any purpose.
|
||||
<p>
|
||||
Updated: Mar 6, 2001
|
||||
</div>
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
|
||||
<title>Overridable Virtual Functions</title>
|
||||
|
||||
<img src="../../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center"
|
||||
width="277" height="86">
|
||||
|
||||
<h1>Overridable Virtual Functions</h1>
|
||||
|
||||
<p>
|
||||
In the <a href="exporting_classes.html">previous example</a> we exposed a simple
|
||||
C++ class in Python and showed that we could write a subclass. We even
|
||||
redefined one of the functions in our derived class. Now we will learn
|
||||
how to make the function behave virtually <em>when called from C++</em>.
|
||||
|
||||
|
||||
<h2><a name="overriding_example">Example</a></h2>
|
||||
|
||||
<p>In this example, it is assumed that <code>hello::greet()</code> is a virtual
|
||||
member function:
|
||||
|
||||
<blockquote><pre>
|
||||
class hello
|
||||
{
|
||||
public:
|
||||
hello(const std::string& country) { this->country = country; }
|
||||
<b>virtual</b> std::string greet() const { return "Hello from " + country; }
|
||||
virtual ~hello(); // Good practice
|
||||
...
|
||||
};
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
We'll need a derived class<a href="#why_derived">*</a> to help us
|
||||
dispatch the call to Python. In our derived class, we need the following
|
||||
elements:
|
||||
|
||||
<ol>
|
||||
|
||||
<li><a name="derived_1">A</a> <code>PyObject*</code> data member (usually
|
||||
called <tt>self</tt>) that holds a pointer to the Python object corresponding
|
||||
to our C++ <tt>hello</tt> instance.
|
||||
|
||||
<li><a name="derived_2">For</a> each exposed constructor of the
|
||||
base class <tt>T</tt>, a constructor which takes the same parameters preceded by an initial
|
||||
<code>PyObject*</code> argument. The initial argument should be stored in the <tt>self</tt> data
|
||||
member described above.
|
||||
|
||||
<li><a name="derived_3">If</a> the class being wrapped is ever returned <i>by
|
||||
value</i> from a wrapped function, be sure you do the same for the
|
||||
<tt>T</tt>'s copy constructor: you'll need a constructor taking arguments
|
||||
<tt>(PyObject*, const T&)</tt>.
|
||||
|
||||
<li><a name="derived_4">An</a> implementation of each virtual function you may
|
||||
wish to override in Python which uses
|
||||
<tt>callback<</tt><i>return-type</i><tt>>::call_method(self, "</tt><i>name</i><tt>", </tt><i>args...</i><tt>)</tt> to call
|
||||
the Python override.
|
||||
|
||||
<li><a name="derived_5">For</a> each non-pure virtual function meant to be
|
||||
overridable from Python, a static member function (or a free function) taking
|
||||
a reference or pointer to the <tt>T</tt> as the first parameter and which
|
||||
forwards any additional parameters neccessary to the <i>default</i>
|
||||
implementation of the virtual function. See also <a href="#private">this
|
||||
note</a> if the base class virtual function is private.
|
||||
|
||||
</ol>
|
||||
|
||||
<blockquote><pre>
|
||||
struct hello_callback : hello
|
||||
{
|
||||
// hello constructor storing initial self_ parameter
|
||||
hello_callback(PyObject* self_, const std::string& x) // <a href="#derived_2">2</a>
|
||||
: hello(x), self(self_) {}
|
||||
|
||||
// In case hello is returned by-value from a wrapped function
|
||||
hello_callback(PyObject* self_, const hello& x) // <a href="#derived_3">3</a>
|
||||
: hello(x), self(self_) {}
|
||||
|
||||
// Override greet to call back into Python
|
||||
std::string greet() const // <a href="#derived_4">4</a>
|
||||
{ return boost::python::callback<std::string>::call_method(self, "greet"); }
|
||||
|
||||
// Supplies the default implementation of greet
|
||||
static std::string <a name= "default_implementation">default_greet</a>(const hello& self_) const // <a href="#derived_5">5</a>
|
||||
{ return self_.hello::greet(); }
|
||||
private:
|
||||
PyObject* self; // <a href="#derived_1">1</a>
|
||||
};
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Finally, we add <tt>hello_callback</tt> to the <tt>
|
||||
class_builder<></tt> declaration in our module initialization
|
||||
function, and when we define the function, we must tell Boost.Python about the default
|
||||
implementation:
|
||||
|
||||
<blockquote><pre>
|
||||
// Create the <a name=
|
||||
"hello_class">Python type object</a> for our extension class
|
||||
boost::python::class_builder<hello<strong>,hello_callback></strong> hello_class(hello, "hello");
|
||||
// Add a virtual member function
|
||||
hello_class.def(&hello::greet, "greet", &<b>hello_callback::default_greet</b>);
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Now our Python subclass of <tt>hello</tt> behaves as expected:
|
||||
|
||||
<blockquote><pre>
|
||||
>>> class wordy(hello):
|
||||
... def greet(self):
|
||||
... return hello.greet(self) + ', where the weather is fine'
|
||||
...
|
||||
>>> hi2 = wordy('Florida')
|
||||
>>> hi2.greet()
|
||||
'Hello from Florida, where the weather is fine'
|
||||
>>> invite(hi2)
|
||||
'Hello from Florida, where the weather is fine! Please come soon!'
|
||||
</pre></blockquote>
|
||||
<p>
|
||||
<a name="why_derived">*</a>You may ask, "Why do we need this derived
|
||||
class? This could have been designed so that everything gets done right
|
||||
inside of <tt>hello</tt>." One of the goals of Boost.Python is to be
|
||||
minimally intrusive on an existing C++ design. In principle, it should be
|
||||
possible to expose the interface for a 3rd party library without changing
|
||||
it. To unintrusively hook into the virtual functions so that a Python
|
||||
override may be called, we must use a derived class.
|
||||
|
||||
<h2>Pure Virtual Functions</h2>
|
||||
|
||||
<p>
|
||||
A pure virtual function with no implementation is actually a lot easier to
|
||||
deal with than a virtual function with a default implementation. First of
|
||||
all, you obviously don't need to <a href="#default_implementation"> supply
|
||||
a default implementation</a>. Secondly, you don't need to call
|
||||
<tt>def()</tt> on the <tt>extension_class<></tt> instance
|
||||
for the virtual function. In fact, you wouldn't <em>want</em> to: if the
|
||||
corresponding attribute on the Python class stays undefined, you'll get an
|
||||
<tt>AttributeError</tt> in Python when you try to call the function,
|
||||
indicating that it should have been implemented. For example:
|
||||
<blockquote>
|
||||
<pre>
|
||||
struct baz {
|
||||
<strong>virtual</strong> int pure(int) = 0;
|
||||
int calls_pure(int x) { return pure(x) + 1000; }
|
||||
};
|
||||
|
||||
struct baz_callback {
|
||||
int pure(int x) { boost::python::callback<int>::call_method(m_self, "pure", x); }
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(foobar)
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::python::module_builder foobar("foobar");
|
||||
boost::python::class_builder<baz,baz_callback> baz_class("baz");
|
||||
baz_class.def(&baz::calls_pure, "calls_pure");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
boost::python::handle_exception(); // Deal with the exception for Python
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>
|
||||
Now in Python:
|
||||
<blockquote>
|
||||
<pre>
|
||||
>>> from foobar import baz
|
||||
>>> x = baz()
|
||||
>>> x.pure(1)
|
||||
Traceback (innermost last):
|
||||
File "<stdin>", line 1, in ?
|
||||
AttributeError: pure
|
||||
>>> x.calls_pure(1)
|
||||
Traceback (innermost last):
|
||||
File "<stdin>", line 1, in ?
|
||||
AttributeError: pure
|
||||
>>> class mumble(baz):
|
||||
... def pure(self, x): return x + 1
|
||||
...
|
||||
>>> y = mumble()
|
||||
>>> y.pure(99)
|
||||
100
|
||||
>>> y.calls_pure(99)
|
||||
1100
|
||||
</pre></blockquote>
|
||||
|
||||
<a name="private"><h2>Private Non-Pure Virtual Functions</h2></a>
|
||||
|
||||
<p>This is one area where some minor intrusiveness on the wrapped library is
|
||||
required. Once it has been overridden, the only way to call the base class
|
||||
implementation of a private virtual function is to make the derived class a
|
||||
friend of the base class. You didn't hear it from me, but most C++
|
||||
implementations will allow you to change the declaration of the base class in
|
||||
this limited way without breaking binary compatibility (though it will certainly
|
||||
break the <a
|
||||
href="http://cs.calvin.edu/c++/C++Standard-Nov97/basic.html#basic.def.odr">ODR</a>).
|
||||
|
||||
<hr>
|
||||
<p>
|
||||
Next: <a href="overloading.html">Function Overloading</a>
|
||||
Previous: <a href="exporting_classes.html">Exporting Classes</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2001. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is" without
|
||||
express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.
|
||||
<p>
|
||||
Updated: Mar 21, 2001
|
||||
|
||||
272
doc/pickle.html
@@ -1,272 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
|
||||
<title>Boost.Python Pickle Support</title>
|
||||
|
||||
<div>
|
||||
|
||||
<img src="../../../c++boost.gif"
|
||||
alt="c++boost.gif (8819 bytes)"
|
||||
align="center"
|
||||
width="277" height="86">
|
||||
|
||||
<hr>
|
||||
<h1>Boost.Python Pickle Support</h1>
|
||||
|
||||
Pickle is a Python module for object serialization, also known
|
||||
as persistence, marshalling, or flattening.
|
||||
|
||||
<p>
|
||||
It is often necessary to save and restore the contents of an object to
|
||||
a file. One approach to this problem is to write a pair of functions
|
||||
that read and write data from a file in a special format. A powerful
|
||||
alternative approach is to use Python's pickle module. Exploiting
|
||||
Python's ability for introspection, the pickle module recursively
|
||||
converts nearly arbitrary Python objects into a stream of bytes that
|
||||
can be written to a file.
|
||||
|
||||
<p>
|
||||
The Boost Python Library supports the pickle module by emulating the
|
||||
interface implemented by Jim Fulton's ExtensionClass module that is
|
||||
included in the
|
||||
<a href="http://www.zope.org/"
|
||||
>ZOPE</a>
|
||||
distribution.
|
||||
This interface is similar to that for regular Python classes as
|
||||
described in detail in the
|
||||
<a href="http://www.python.org/doc/current/lib/module-pickle.html"
|
||||
>Python Library Reference for pickle.</a>
|
||||
|
||||
<hr>
|
||||
<h2>The Boost.Python Pickle Interface</h2>
|
||||
|
||||
At the user level, the Boost.Python pickle interface involves three special
|
||||
methods:
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<strong><tt>__getinitargs__</tt></strong>
|
||||
<dd>
|
||||
When an instance of a Boost.Python extension class is pickled, the
|
||||
pickler tests if the instance has a <tt>__getinitargs__</tt> method.
|
||||
This method must return a Python tuple (it is most convenient to use
|
||||
a boost::python::tuple). When the instance is restored by the
|
||||
unpickler, the contents of this tuple are used as the arguments for
|
||||
the class constructor.
|
||||
|
||||
<p>
|
||||
If <tt>__getinitargs__</tt> is not defined, the class constructor
|
||||
will be called without arguments.
|
||||
|
||||
<p>
|
||||
<dt>
|
||||
<strong><tt>__getstate__</tt></strong>
|
||||
|
||||
<dd>
|
||||
When an instance of a Boost.Python extension class is pickled, the
|
||||
pickler tests if the instance has a <tt>__getstate__</tt> method.
|
||||
This method should return a Python object representing the state of
|
||||
the instance.
|
||||
|
||||
<p>
|
||||
If <tt>__getstate__</tt> is not defined, the instance's
|
||||
<tt>__dict__</tt> is pickled (if it is not empty).
|
||||
|
||||
<p>
|
||||
<dt>
|
||||
<strong><tt>__setstate__</tt></strong>
|
||||
|
||||
<dd>
|
||||
When an instance of a Boost.Python extension class is restored by the
|
||||
unpickler, it is first constructed using the result of
|
||||
<tt>__getinitargs__</tt> as arguments (see above). Subsequently the
|
||||
unpickler tests if the new instance has a <tt>__setstate__</tt>
|
||||
method. If so, this method is called with the result of
|
||||
<tt>__getstate__</tt> (a Python object) as the argument.
|
||||
|
||||
<p>
|
||||
If <tt>__setstate__</tt> is not defined, the result of
|
||||
<tt>__getstate__</tt> must be a Python dictionary. The items of this
|
||||
dictionary are added to the instance's <tt>__dict__</tt>.
|
||||
|
||||
</dl>
|
||||
|
||||
If both <tt>__getstate__</tt> and <tt>__setstate__</tt> are defined,
|
||||
the Python object returned by <tt>__getstate__</tt> need not be a
|
||||
dictionary. The <tt>__getstate__</tt> and <tt>__setstate__</tt> methods
|
||||
can do what they want.
|
||||
|
||||
<hr>
|
||||
<h2>Pitfalls and Safety Guards</h2>
|
||||
|
||||
In Boost.Python extension modules with many extension classes,
|
||||
providing complete pickle support for all classes would be a
|
||||
significant overhead. In general complete pickle support should only be
|
||||
implemented for extension classes that will eventually be pickled.
|
||||
However, the author of a Boost.Python extension module might not
|
||||
anticipate correctly which classes need support for pickle.
|
||||
Unfortunately, the pickle protocol described above has two important
|
||||
pitfalls that the end user of a Boost.Python extension module might not
|
||||
be aware of:
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<strong>Pitfall 1:</strong>
|
||||
Both <tt>__getinitargs__</tt> and <tt>__getstate__</tt> are not defined.
|
||||
|
||||
<dd>
|
||||
In this situation the unpickler calls the class constructor without
|
||||
arguments and then adds the <tt>__dict__</tt> that was pickled by
|
||||
default to that of the new instance.
|
||||
|
||||
<p>
|
||||
However, most C++ classes wrapped with Boost.Python will have member
|
||||
data that are not restored correctly by this procedure. To alert the
|
||||
user to this problem, a safety guard is provided. If both
|
||||
<tt>__getinitargs__</tt> and <tt>__getstate__</tt> are not defined,
|
||||
Boost.Python tests if the class has an attribute
|
||||
<tt>__dict_defines_state__</tt>. An exception is raised if this
|
||||
attribute is not defined:
|
||||
|
||||
<pre>
|
||||
RuntimeError: Incomplete pickle support (__dict_defines_state__ not set)
|
||||
</pre>
|
||||
|
||||
In the rare cases where this is not the desired behavior, the safety
|
||||
guard can deliberately be disabled. The corresponding C++ code for
|
||||
this is, e.g.:
|
||||
|
||||
<pre>
|
||||
class_builder<your_class> py_your_class(your_module, "your_class");
|
||||
py_your_class.dict_defines_state();
|
||||
</pre>
|
||||
|
||||
It is also possible to override the safety guard at the Python level.
|
||||
E.g.:
|
||||
|
||||
<pre>
|
||||
import your_bpl_module
|
||||
class your_class(your_bpl_module.your_class):
|
||||
__dict_defines_state__ = 1
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<dt>
|
||||
<strong>Pitfall 2:</strong>
|
||||
<tt>__getstate__</tt> is defined and the instance's <tt>__dict__</tt> is not empty.
|
||||
|
||||
<dd>
|
||||
The author of a Boost.Python extension class might provide a
|
||||
<tt>__getstate__</tt> method without considering the possibilities
|
||||
that:
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>
|
||||
his class is used in Python as a base class. Most likely the
|
||||
<tt>__dict__</tt> of instances of the derived class needs to be
|
||||
pickled in order to restore the instances correctly.
|
||||
|
||||
<p>
|
||||
<li>
|
||||
the user adds items to the instance's <tt>__dict__</tt> directly.
|
||||
Again, the <tt>__dict__</tt> of the instance then needs to be
|
||||
pickled.
|
||||
|
||||
</ul>
|
||||
<p>
|
||||
|
||||
To alert the user to this highly unobvious problem, a safety guard is
|
||||
provided. If <tt>__getstate__</tt> is defined and the instance's
|
||||
<tt>__dict__</tt> is not empty, Boost.Python tests if the class has
|
||||
an attribute <tt>__getstate_manages_dict__</tt>. An exception is
|
||||
raised if this attribute is not defined:
|
||||
|
||||
<pre>
|
||||
RuntimeError: Incomplete pickle support (__getstate_manages_dict__ not set)
|
||||
</pre>
|
||||
|
||||
To resolve this problem, it should first be established that the
|
||||
<tt>__getstate__</tt> and <tt>__setstate__</tt> methods manage the
|
||||
instances's <tt>__dict__</tt> correctly. Note that this can be done
|
||||
both at the C++ and the Python level. Finally, the safety guard
|
||||
should intentionally be overridden. E.g. in C++:
|
||||
|
||||
<pre>
|
||||
class_builder<your_class> py_your_class(your_module, "your_class");
|
||||
py_your_class.getstate_manages_dict();
|
||||
</pre>
|
||||
|
||||
In Python:
|
||||
|
||||
<pre>
|
||||
import your_bpl_module
|
||||
class your_class(your_bpl_module.your_class):
|
||||
__getstate_manages_dict__ = 1
|
||||
def __getstate__(self):
|
||||
# your code here
|
||||
def __setstate__(self, state):
|
||||
# your code here
|
||||
</pre>
|
||||
</dl>
|
||||
|
||||
<hr>
|
||||
<h2>Practical Advice</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Avoid using <tt>__getstate__</tt> if the instance can also be
|
||||
reconstructed by way of <tt>__getinitargs__</tt>. This automatically
|
||||
avoids Pitfall 2.
|
||||
|
||||
<p>
|
||||
<li>
|
||||
If <tt>__getstate__</tt> is required, include the instance's
|
||||
<tt>__dict__</tt> in the Python object that is returned.
|
||||
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
<h2>Examples</h2>
|
||||
|
||||
There are three files in <tt>boost/libs/python/example</tt> that
|
||||
show how so provide pickle support.
|
||||
|
||||
<h3><a href="../example/pickle1.cpp"><tt>pickle1.cpp</tt></a></h3>
|
||||
|
||||
The C++ class in this example can be fully restored by passing the
|
||||
appropriate argument to the constructor. Therefore it is sufficient
|
||||
to define the pickle interface method <tt>__getinitargs__</tt>.
|
||||
|
||||
<h3><a href="../example/pickle2.cpp"><tt>pickle2.cpp</tt></a></h3>
|
||||
|
||||
The C++ class in this example contains member data that cannot be
|
||||
restored by any of the constructors. Therefore it is necessary to
|
||||
provide the <tt>__getstate__</tt>/<tt>__setstate__</tt> pair of
|
||||
pickle interface methods.
|
||||
|
||||
<p>
|
||||
For simplicity, the <tt>__dict__</tt> is not included in the result
|
||||
of <tt>__getstate__</tt>. This is not generally recommended, but a
|
||||
valid approach if it is anticipated that the object's
|
||||
<tt>__dict__</tt> will always be empty. Note that the safety guards
|
||||
will catch the cases where this assumption is violated.
|
||||
|
||||
<h3><a href="../example/pickle3.cpp"><tt>pickle3.cpp</tt></a></h3>
|
||||
|
||||
This example is similar to <a
|
||||
href="../example/pickle2.cpp"><tt>pickle2.cpp</tt></a>. However, the
|
||||
object's <tt>__dict__</tt> is included in the result of
|
||||
<tt>__getstate__</tt>. This requires more code but is unavoidable
|
||||
if the object's <tt>__dict__</tt> is not always empty.
|
||||
|
||||
<hr>
|
||||
© Copyright Ralf W. Grosse-Kunstleve 2001. Permission to copy,
|
||||
use, modify, sell and distribute this document is granted provided this
|
||||
copyright notice appears in all copies. This document is provided "as
|
||||
is" without express or implied warranty, and with no claim as to its
|
||||
suitability for any purpose.
|
||||
|
||||
<p>
|
||||
Updated: March 21, 2001
|
||||
</div>
|
||||
@@ -1,148 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<title>
|
||||
Pointers
|
||||
</title>
|
||||
<div>
|
||||
<h1>
|
||||
<img width="277" height="86" id="_x0000_i1025" align="center"
|
||||
src="../../../c++boost.gif" alt= "c++boost.gif (8819 bytes)">Pointers
|
||||
</h1>
|
||||
|
||||
<h2><a name="problem">The Problem With Pointers</a></h2>
|
||||
|
||||
<p>
|
||||
In general, raw pointers passed to or returned from functions are problematic
|
||||
for Boost.Python because pointers have too many potential meanings. Is it an iterator?
|
||||
A pointer to a single element? An array? When used as a return value, is the
|
||||
caller expected to manage (delete) the pointed-to object or is the pointer
|
||||
really just a reference? If the latter, what happens to Python references to the
|
||||
referent when some C++ code deletes it?
|
||||
<p>
|
||||
There are a few cases in which pointers are converted automatically:
|
||||
<ul>
|
||||
|
||||
<li>Both const- and non-const pointers to wrapped class instances can be passed
|
||||
<i>to</i> C++ functions.
|
||||
|
||||
<li>Values of type <code>const char*</code> are interpreted as
|
||||
null-terminated 'C' strings and when passed to or returned from C++ functions are
|
||||
converted from/to Python strings.
|
||||
|
||||
</ul>
|
||||
|
||||
<h3>Can you avoid the problem?</h3>
|
||||
|
||||
<p>My first piece of advice to anyone with a case not covered above is
|
||||
``find a way to avoid the problem.'' For example, if you have just one
|
||||
or two functions that return a pointer to an individual <code>const
|
||||
T</code>, and <code>T</code> is a wrapped class, you may be able to write a ``thin
|
||||
converting wrapper'' over those two functions as follows:
|
||||
|
||||
<blockquote><pre>
|
||||
const Foo* f(); // original function
|
||||
const Foo& f_wrapper() { return *f(); }
|
||||
...
|
||||
my_module.def(f_wrapper, "f");
|
||||
</pre></blockquote>
|
||||
<p>
|
||||
Foo must have a public copy constructor for this technique to work, since Boost.Python
|
||||
converts <code>const T&</code> values <code>to_python</code> by copying the <code>T</code>
|
||||
value into a new extension instance.
|
||||
|
||||
<h2>Dealing with the problem</h2>
|
||||
|
||||
<p>The first step in handling the remaining cases is to figure out what the pointer
|
||||
means. Several potential solutions are provided in the examples that follow:
|
||||
|
||||
<h3>Returning a pointer to a wrapped type</h3>
|
||||
|
||||
<h4>Returning a const pointer</h4>
|
||||
|
||||
<p>If you have lots of functions returning a <code>const T*</code> for some
|
||||
wrapped <code>T</code>, you may want to provide an automatic
|
||||
<code>to_python</code> conversion function so you don't have to write lots of
|
||||
thin wrappers. You can do this simply as follows:
|
||||
|
||||
<blockquote><pre>
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
|
||||
PyObject* to_python(const Foo* p) {
|
||||
return to_python(*p); // convert const Foo* in terms of const Foo&
|
||||
}
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
</pre></blockquote>
|
||||
|
||||
<h4>If you can't (afford to) copy the referent, or the pointer is non-const</h4>
|
||||
|
||||
<p>If the wrapped type doesn't have a public copy constructor, if copying is
|
||||
<i>extremely</i> costly (remember, we're dealing with Python here), or if the
|
||||
pointer is non-const and you really need to be able to modify the referent from
|
||||
Python, you can use the following dangerous trick. Why dangerous? Because python
|
||||
can not control the lifetime of the referent, so it may be destroyed by your C++
|
||||
code before the last Python reference to it disappears:
|
||||
|
||||
<blockquote><pre>
|
||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
|
||||
PyObject* to_python(Foo* p)
|
||||
{
|
||||
return boost::python::python_extension_class_converters<Foo>::ptr_to_python(p);
|
||||
}
|
||||
|
||||
PyObject* to_python(const Foo* p)
|
||||
{
|
||||
return to_python(const_cast<Foo*>(p));
|
||||
}
|
||||
BOOST_PYTHON_END_CONVERSION_NAMESPACE
|
||||
</pre></blockquote>
|
||||
|
||||
This will cause the Foo* to be treated as though it were an owning smart
|
||||
pointer, even though it's not. Be sure you don't use the reference for anything
|
||||
from Python once the pointer becomes invalid, though. Don't worry too much about
|
||||
the <code>const_cast<></code> above: Const-correctness is completely lost
|
||||
to Python anyway!
|
||||
|
||||
<h3>[In/]Out Parameters and Immutable Types</h3>
|
||||
|
||||
<p>If you have an interface that uses non-const pointers (or references) as
|
||||
in/out parameters to types which in Python are immutable (e.g. int, string),
|
||||
there simply is <i>no way</i> to get the same interface in Python. You must
|
||||
resort to transforming your interface with simple thin wrappers as shown below:
|
||||
<blockquote><pre>
|
||||
const void f(int* in_out_x); // original function
|
||||
const int f_wrapper(int in_x) { f(in_x); return in_x; }
|
||||
...
|
||||
my_module.def(f_wrapper, "f");
|
||||
</pre></blockquote>
|
||||
|
||||
<p>Of course, [in/]out parameters commonly occur only when there is already a
|
||||
return value. You can handle this case by returning a Python tuple:
|
||||
<blockquote><pre>
|
||||
typedef unsigned ErrorCode;
|
||||
const char* f(int* in_out_x); // original function
|
||||
...
|
||||
#include <boost/python/objects.hpp>
|
||||
const boost::python::tuple f_wrapper(int in_x) {
|
||||
const char* s = f(in_x);
|
||||
return boost::python::tuple(s, in_x);
|
||||
}
|
||||
...
|
||||
my_module.def(f_wrapper, "f");
|
||||
</pre></blockquote>
|
||||
<p>Now, in Python:
|
||||
<blockquote><pre>
|
||||
>>> str,out_x = f(3)
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
Previous: <a href="enums.html">Enums</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is" without
|
||||
express or implied warranty, and with no claim as to its suitability
|
||||
for any purpose.
|
||||
<p>
|
||||
Updated: Nov 26, 2000
|
||||
</div>
|
||||
|
||||
222
doc/polymorphism.txt
Normal file
@@ -0,0 +1,222 @@
|
||||
.. Copyright David Abrahams 2006. Distributed under the Boost
|
||||
.. Software License, Version 1.0. (See accompanying
|
||||
.. file LICENSE_1_0.txt or copy at
|
||||
.. http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
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?
|
||||
|
||||
|
||||
466
doc/projects.html
Normal file
@@ -0,0 +1,466 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Cygwin (vers 1st September 2004), see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html">
|
||||
<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="../../../boost.png" 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</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>Games</h3>
|
||||
|
||||
<dl>
|
||||
<dt><b><a href="http://www.firaxis.com">Civilization IV</a></b></dt>
|
||||
</dl>
|
||||
|
||||
<blockquote>
|
||||
“The fourth game in the PC strategy series that has sold over five
|
||||
million copies, Sid Meier's Civilization IV is a bold step forward for
|
||||
the franchise, with spectacular new 3D graphics and all-new single and
|
||||
multiplayer content. Civilization IV will also set a new standard for
|
||||
user-modification, allowing gamers to create their own add-ons using
|
||||
Python and XML.
|
||||
|
||||
<p>Sid Meier's Civilization IV will be released for PC in late 2005. For
|
||||
more information please visit <a href=
|
||||
"http://www.firaxis.com">http://www.firaxis.com</a> or write <a href=
|
||||
"mailto:kgilmore@firaxis.com">kgilmore@firaxis.com</a>”</p>
|
||||
</blockquote>
|
||||
|
||||
<p>Boost.Python is used as the interface layer between the C++ game code
|
||||
and Python. Python is used for many purposes in the game, including map
|
||||
generation, interface screens, game events, tools, tutorials, etc. Most
|
||||
high-level game operations have been exposed to Python in order to give
|
||||
modders the power they need to customize the game.</p>
|
||||
|
||||
<blockquote>
|
||||
-Mustafa Thamer, Civ4 Lead Programmer
|
||||
</blockquote>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><b><a href="http://vegastrike.sourceforge.net">Vega
|
||||
Strike</a></b></dt>
|
||||
|
||||
<dd>
|
||||
<a href="http://vegastrike.sourceforge.net">Vega Strike</a> is the 3D
|
||||
Space Simulator that allows you to trade and bounty hunt in a vast
|
||||
universe. Players face dangers, decisions, piracy, and aliens.
|
||||
|
||||
<p><a href="http://vegastrike.sourceforge.net">Vega Strike</a> has
|
||||
decided to base its scripting on python, using boost as the layer
|
||||
between the class hierarchy in python and the class hierarchy in C++.
|
||||
The result is a very flexible scripting system that treats units as
|
||||
native python classes when designing missions or writing AI's.</p>
|
||||
|
||||
<p>A large economic and planetary simulation is currently being run in
|
||||
the background in python and the results are returned back into C++ in
|
||||
the form of various factions' spaceships appearing near worlds that
|
||||
they are simulated to be near in python if the player is in the general
|
||||
neighborhood.</p>
|
||||
</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>
|
||||
</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>
|
||||
|
||||
</dd>
|
||||
|
||||
<dt><a href="http://www.iplt.org"><b>IPLT</b></a></dt>
|
||||
|
||||
<dd>
|
||||
<a href="mailto:ansgar.philippsen-at-unibas.ch">Ansgar Philippsen</a>
|
||||
writes:
|
||||
|
||||
<blockquote>
|
||||
IPLT is an image processing library and toolbox for the structural
|
||||
biology electron microscopy community. I would call it a
|
||||
budding/evolving project, since it is currently not in production
|
||||
stage, but rather under heavy development. Python is used as the main
|
||||
scripting/interaction level, but also for rapid prototyping, since
|
||||
the underlying C++ class library is pretty much fully exposed via
|
||||
boost.python (at least the high-level interface). The combined power
|
||||
of C++ and Python for this project turned out to be just awesome.
|
||||
</blockquote><br>
|
||||
|
||||
</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>
|
||||
</dd>
|
||||
|
||||
<dt><a href="http://www.vpython.org"><b>VPython</b></a></dt>
|
||||
|
||||
<dd>
|
||||
<a href="mailto:Bruce_Sherwood-at-ncsu.edu">Bruce Sherwood</a> writes:
|
||||
|
||||
<blockquote>
|
||||
VPython is an extension for Python that makes it easy to create
|
||||
navigable 3D animations, which are generated as a side effect of
|
||||
computational code. VPython is used in education for various
|
||||
purposes, including teaching physics and programming, but it has also
|
||||
been used by research scientists to visualize systems or data in 3D.
|
||||
</blockquote><br>
|
||||
|
||||
</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 L-BFGS quasi-Newton 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>
|
||||
</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/index.php?pg=dev_projetos">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/index.php?pg=dev_projetos">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://polybori.sourceforge.net/">PolyBoRi</a></b></dt>
|
||||
|
||||
<dd>
|
||||
<p><a href="mailto:brickenstein@mfo.de"
|
||||
>Michael Brickenstein</a> writes:</p>
|
||||
|
||||
<blockquote>
|
||||
<p>The core of PolyBoRi is a C++ library, which provides
|
||||
high-level data types for Boolean polynomials and monomials,
|
||||
exponent vectors, as well as for the underlying polynomial
|
||||
rings and subsets of the powerset of the Boolean variables. As
|
||||
a unique approach, binary decision diagrams are used as
|
||||
internal storage type for polynomial structures. On top of
|
||||
this C++-library we provide a Python interface. This allows
|
||||
parsing of complex polynomial systems, as well as sophisticated
|
||||
and extendable strategies for Gröbner basis computation.
|
||||
Boost.Python has helped us to create this interface in a
|
||||
very clean way.</p>
|
||||
</blockquote>
|
||||
</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>Systems Libraries</h3>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://itamarst.org/software"><b>Fusion</b></a></dt>
|
||||
|
||||
<dd>
|
||||
<p>Fusion is a library that supports implementing protocols in C++ for
|
||||
use with Twisted, allowing control over memory allocation strategies,
|
||||
fast method calls internally, etc.. Fusion supports TCP, UDP and
|
||||
multicast, and is implemented using the Boost.Python python
|
||||
bindings.</p>
|
||||
|
||||
<p>Fusion is licensed under the MIT license, and available for download
|
||||
from <a href=
|
||||
"http://itamarst.org/software">http://itamarst.org/software</a>.</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 -->
|
||||
29 May, 2008</p>
|
||||
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002-2008.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
905
doc/special.html
@@ -1,905 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<title>
|
||||
Special Method and Operator Support
|
||||
</title>
|
||||
<div>
|
||||
<h1>
|
||||
<img width="277" height="86" id="_x0000_i1025" align="middle" src=
|
||||
"../../../c++boost.gif" alt="c++boost.gif (8819 bytes)">Special Method and
|
||||
Operator Support
|
||||
</h1>
|
||||
<h2>
|
||||
Overview
|
||||
</h2>
|
||||
<p>
|
||||
Boost.Python supports all of the standard <a href=
|
||||
"http://www.python.org/doc/current/ref/specialnames.html">
|
||||
special method names</a> supported by real Python class instances <em>
|
||||
except</em> <code>__complex__</code> (more on the reasons <a href=
|
||||
"#reasons">below</a>). In addition, it can quickly and easily expose
|
||||
suitable C++ functions and operators as Python operators. The following
|
||||
categories of special method names are supported:
|
||||
<ul>
|
||||
<li><a href="#general">Basic Customization</a>
|
||||
<li><a href="#numeric">Numeric Operators</a>
|
||||
<li><a href="#sequence_and_mapping">Sequence and Mapping protocols</a>
|
||||
<li><a href="#getter_setter">Attribute Getters and Setters</a>
|
||||
</ul>
|
||||
|
||||
<h2><a name="general">Basic Customization</a></h2>
|
||||
|
||||
|
||||
<p>
|
||||
Python provides a number of special operators for basic customization of a
|
||||
class. Only a brief description is provided below; more complete
|
||||
documentation can be found <a
|
||||
href="http://www.python.org/doc/current/ref/customization.html">here</a>.
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<b><tt class='method'>__init__</tt></b>(<i>self</i>)
|
||||
<dd>
|
||||
Initialize the class instance. For extension classes not subclassed in
|
||||
Python, <code> __init__</code> is defined by
|
||||
|
||||
<pre> my_class.def(boost::python::constructor<...>())</pre>
|
||||
|
||||
(see section <a href="example1.html">"A Simple Example Using Boost.Python"</a>).<p>
|
||||
<dt>
|
||||
<b><tt class='method'>__del__</tt></b>(<i>self</i>)
|
||||
<dd>
|
||||
Called when the extension instance is about to be destroyed. For extension classes
|
||||
not subclassed in Python, <code> __del__</code> is always defined automatically by
|
||||
means of the class' destructor.
|
||||
<dt>
|
||||
<b><tt class='method'>__repr__</tt></b>(<i>self</i>)
|
||||
<dd>
|
||||
Create a string representation from which the object can be
|
||||
reconstructed.
|
||||
<dt>
|
||||
<b><tt class='method'>__str__</tt></b>(<i>self</i>)
|
||||
<dd>
|
||||
Create a string representation which is suitable for printing.
|
||||
<dt>
|
||||
<b><tt class='method'>__cmp__</tt></b>(<i>self, other</i>)
|
||||
<dd>
|
||||
Three-way compare function, used to implement comparison operators
|
||||
(< etc.) Should return a negative integer if <code> self < other
|
||||
</code> , zero if <code> self == other </code> , a positive integer if
|
||||
<code> self > other </code>.
|
||||
<dt>
|
||||
<b><tt class='method'>__hash__</tt></b>(<i>self</i>)
|
||||
<dd>
|
||||
Called for the key object for dictionary operations, and by the
|
||||
built-in function hash(). Should return a 32-bit integer usable as a
|
||||
hash value for dictionary operations (only allowed if __cmp__ is also
|
||||
defined)
|
||||
<dt>
|
||||
<b><tt class='method'>__nonzero__</tt></b>(<i>self</i>)
|
||||
<dd>
|
||||
called if the object is used as a truth value (e.g. in an if
|
||||
statement)
|
||||
<dt>
|
||||
<b><tt class='method'>__call__</tt></b> (<var>self</var><big>[</big><var>, args...</var><big>]</big>)
|
||||
<dd>
|
||||
Called when the instance is ``called'' as a function; if this method
|
||||
is defined, <code><var>x</var>(arg1, arg2, ...)</code> is a shorthand for
|
||||
<code><var>x</var>.__call__(arg1, arg2, ...)</code>.
|
||||
</dl>
|
||||
|
||||
If we have a suitable C++ function that supports any of these features,
|
||||
we can export it like any other function, using its Python special name.
|
||||
For example, suppose that class <code>Foo</code> provides a string
|
||||
conversion function:
|
||||
<blockquote><pre>
|
||||
std::string to_string(Foo const& f)
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << f;
|
||||
return s.str();
|
||||
}
|
||||
</pre></blockquote>
|
||||
This function would be wrapped like this:
|
||||
<blockquote><pre>
|
||||
boost::python::class_builder<Foo> foo_class(my_module, "Foo");
|
||||
foo_class.def(&to_string, "__str__");
|
||||
</pre></blockquote>
|
||||
Note that Boost.Python also supports <em>automatic wrapping</em> of
|
||||
<code>__str__</code> and <code>__cmp__</code>. This is explained in the <a
|
||||
href="#numeric">next section</a> and the <a href="#numeric_table">Table of
|
||||
Automatically Wrapped Methods</a>.
|
||||
|
||||
<h2><a name="numeric">Numeric Operators</a></h2>
|
||||
|
||||
<p>
|
||||
Numeric operators can be exposed manually, by <code>def</code>ing C++
|
||||
[member] functions that support the standard Python <a
|
||||
href="http://www.python.org/doc/current/ref/numeric-types.html">numeric
|
||||
protocols</a>. This is the same basic technique used to expose
|
||||
<code>to_string()</code> as <code>__str__()</code> above, and is <a
|
||||
href="#numeric_manual">covered in detail below</a>. Boost.Python also supports
|
||||
<i>automatic wrapping</i> of numeric operators whenever they have already
|
||||
been defined in C++.
|
||||
|
||||
<h3><a name="numeric_auto">Exposing C++ Operators Automatically</a></h3>
|
||||
|
||||
<p>
|
||||
Supose we wanted to expose a C++ class
|
||||
<code>BigNum</code> which supports addition. That is, in C++ we can write:
|
||||
<blockquote><pre>
|
||||
BigNum a, b, c;
|
||||
...
|
||||
c = a + b;
|
||||
</pre></blockquote>
|
||||
<p>
|
||||
To enable the same functionality in Python, we first wrap the <code>
|
||||
BigNum</code> class as usual:
|
||||
<blockquote><pre>
|
||||
boost::python::class_builder<BigNum> bignum_class(my_module, "BigNum");
|
||||
bignum_class.def(boost::python::constructor<>());
|
||||
...
|
||||
</pre></blockquote>
|
||||
Then we export the addition operator like this:
|
||||
|
||||
<blockquote><pre>
|
||||
bignum_class.def(boost::python::operators<boost::python::op_add>());
|
||||
</pre></blockquote>
|
||||
|
||||
Since BigNum also supports subtraction, multiplication, and division, we
|
||||
want to export those also. This can be done in a single command by
|
||||
``or''ing the operator identifiers together (a complete list of these
|
||||
identifiers and the corresponding operators can be found in the <a href=
|
||||
"#numeric_table">Table of Automatically Wrapped Methods</a>):
|
||||
<blockquote><pre>
|
||||
bignum_class.def(boost::python::operators<(boost::python::op_sub | boost::python::op_mul | boost::python::op_div)>());
|
||||
</pre></blockquote>
|
||||
[Note that the or-expression must be enclosed in parentheses.]
|
||||
|
||||
<p>This form of operator definition can be used to wrap unary and
|
||||
homogeneous binary operators (a <i>homogeneous</i> operator has left and
|
||||
right operands of the same type). Now suppose that our C++ library also
|
||||
supports addition of BigNums and plain integers:
|
||||
|
||||
<blockquote><pre>
|
||||
BigNum a, b;
|
||||
int i;
|
||||
...
|
||||
a = b + i;
|
||||
a = i + b;
|
||||
</pre></blockquote>
|
||||
To wrap these heterogeneous operators, we need to specify a different type for
|
||||
one of the operands. This is done using the <code>right_operand</code>
|
||||
and <code>left_operand</code> templates:
|
||||
<blockquote><pre>
|
||||
bignum_class.def(boost::python::operators<boost::python::op_add>(), boost::python::right_operand<int>());
|
||||
bignum_class.def(boost::python::operators<boost::python::op_add>(), boost::python::left_operand<int>());
|
||||
</pre></blockquote>
|
||||
Boost.Python uses overloading to register several variants of the same
|
||||
operation (more on this in the context of <a href="#coercion">
|
||||
coercion</a>). Again, several operators can be exported at once:
|
||||
<blockquote><pre>
|
||||
bignum_class.def(boost::python::operators<(boost::python::op_sub | boost::python::op_mul | boost::python::op_div)>(),
|
||||
boost::python::right_operand<int>());
|
||||
bignum_class.def(boost::python::operators<(boost::python::op_sub | boost::python::op_mul | boost::python::op_div)>(),
|
||||
boost::python::left_operand<int>());
|
||||
</pre></blockquote>
|
||||
The type of the operand not mentioned is taken from the class being wrapped. In
|
||||
our example, the class object is <code>bignum_class</code>, and thus the
|
||||
other operand's type is ``<code>BigNum const&</code>''. You can override
|
||||
this default by explicitly specifying a type in the <code>
|
||||
operators</code> template:
|
||||
<blockquote><pre>
|
||||
bignum_class.def(boost::python::operators<boost::python::op_add, BigNum>(), boost::python::right_operand<int>());
|
||||
</pre></blockquote>
|
||||
<p>
|
||||
Note that automatic wrapping uses the <em>expression</em>
|
||||
``<code>left + right</code>'' and can be used uniformly
|
||||
regardless of whether the C++ operators are supplied as free functions
|
||||
|
||||
<blockquote><pre>
|
||||
BigNum operator+(BigNum, BigNum)
|
||||
</pre></blockquote>
|
||||
|
||||
or as member functions
|
||||
|
||||
<blockquote><pre>
|
||||
BigNum::operator+(BigNum).
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
For the Python built-in functions <code>pow()</code> and
|
||||
<code>abs()</code>, there is no corresponding C++ operator. Instead,
|
||||
automatic wrapping attempts to wrap C++ functions of the same name. This
|
||||
only works if those functions are known in namespace
|
||||
<code>python</code>. On some compilers (e.g. MSVC) it might be
|
||||
necessary to add a using declaration prior to wrapping:
|
||||
|
||||
<blockquote><pre>
|
||||
namespace boost { namespace python {
|
||||
using my_namespace::pow;
|
||||
using my_namespace::abs;
|
||||
}
|
||||
</pre></blockquote>
|
||||
|
||||
<h3><a name="numeric_manual">Wrapping Numeric Operators Manually</a></h3>
|
||||
<p>
|
||||
In some cases, automatic wrapping of operators may be impossible or
|
||||
undesirable. Suppose, for example, that the modulo operation for BigNums
|
||||
is defined by a set of functions called <code>mod()</code>:
|
||||
|
||||
<blockquote><pre>
|
||||
BigNum mod(BigNum const& left, BigNum const& right);
|
||||
BigNum mod(BigNum const& left, int right);
|
||||
BigNum mod(int left, BigNum const& right);
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
For automatic wrapping of the modulo function, <code>operator%()</code> would be needed.
|
||||
Therefore, the <code>mod()</code>-functions must be wrapped manually. That is, we have
|
||||
to export them explicitly with the Python special name "__mod__":
|
||||
|
||||
<blockquote><pre>
|
||||
bignum_class.def((BigNum (*)(BigNum const&, BigNum const&))&mod, "__mod__");
|
||||
bignum_class.def((BigNum (*)(BigNum const&, int))&mod, "__mod__");
|
||||
</pre></blockquote>
|
||||
|
||||
<p>
|
||||
The third form of <code>mod()</code> (with <code>int</code> as left operand) cannot
|
||||
be wrapped directly. We must first create a function <code>rmod()</code> with the
|
||||
operands reversed:
|
||||
|
||||
<blockquote><pre>
|
||||
BigNum rmod(BigNum const& right, int left)
|
||||
{
|
||||
return mod(left, right);
|
||||
}
|
||||
</pre></blockquote>
|
||||
|
||||
This function must be wrapped under the name "__rmod__" (standing for "reverse mod"):
|
||||
|
||||
<blockquote><pre>
|
||||
bignum_class.def(&rmod, "__rmod__");
|
||||
</pre></blockquote>
|
||||
|
||||
Many of the possible operator names can be found in the <a href=
|
||||
"#numeric_table">Table of Automatically Wrapped Methods</a>. Special treatment is
|
||||
necessary to export the <a href="#ternary_pow">ternary pow</a> operator.
|
||||
|
||||
<p>
|
||||
Automatic and manual wrapping can be mixed arbitrarily. Note that you
|
||||
cannot overload the same operator for a given extension class on both
|
||||
``<code>int</code>'' and ``<code>float</code>'', because Python implicitly
|
||||
converts these types into each other. Thus, the overloaded variant
|
||||
found first (be it ``<code>int</code>`` or ``<code>float</code>'') will be
|
||||
used for either of the two types.
|
||||
|
||||
<h3><a name="coercion">Coercion</a></h3>
|
||||
|
||||
|
||||
Plain Python can only execute operators with identical types on the left
|
||||
and right hand side. If it encounters an expression where the types of
|
||||
the left and right operand differ, it tries to coerce these types to a
|
||||
common type before invoking the actual operator. Implementing good
|
||||
coercion functions can be difficult if many type combinations must be
|
||||
supported.
|
||||
<p>
|
||||
Boost.Python solves this problem the same way that C++ does: with <em><a
|
||||
href="overloading.html">overloading</a></em>. This technique drastically
|
||||
simplifies the code neccessary to support operators: you just register
|
||||
operators for all desired type combinations, and Boost.Python automatically
|
||||
ensures that the correct function is called in each case; there is no
|
||||
need for user-defined coercion functions. To enable operator
|
||||
overloading, Boost.Python provides a standard coercion which is <em>implicitly
|
||||
registered</em> whenever automatic operator wrapping is used.
|
||||
<p>
|
||||
If you wrap all operator functions manually, but still want to use
|
||||
operator overloading, you have to register the standard coercion
|
||||
function explicitly:
|
||||
|
||||
<blockquote><pre>
|
||||
// this is not necessary if automatic operator wrapping is used
|
||||
bignum_class.def_standard_coerce();
|
||||
</pre></blockquote>
|
||||
|
||||
If you encounter a situation where you absolutely need a customized
|
||||
coercion, you can still define the "__coerce__" operator manually. The signature
|
||||
of a coercion function should look like one of the following (the first is
|
||||
the safest):
|
||||
|
||||
<blockquote><pre>
|
||||
boost::python::tuple custom_coerce(boost::python::reference left, boost::python::reference right);
|
||||
boost::python::tuple custom_coerce(PyObject* left, PyObject* right);
|
||||
PyObject* custom_coerce(PyObject* left, PyObject* right);
|
||||
</pre></blockquote>
|
||||
|
||||
The resulting <code>tuple</code> must contain two elements which
|
||||
represent the values of <code>left</code> and <code>right</code>
|
||||
converted to the same type. Such a function is wrapped as usual:
|
||||
|
||||
<blockquote><pre>
|
||||
// this must be called before any use of automatic operator
|
||||
// wrapping or a call to some_class.def_standard_coerce()
|
||||
some_class.def(&custom_coerce, "__coerce__");
|
||||
</pre></blockquote>
|
||||
|
||||
Note that the standard coercion (defined by use of automatic
|
||||
operator wrapping on a <code>class_builder</code> or a call to
|
||||
<code>class_builder::def_standard_coerce()</code>) will never be applied if
|
||||
a custom coercion function has been registered. Therefore, in
|
||||
your coercion function you should call
|
||||
|
||||
<blockquote><pre>
|
||||
boost::python::standard_coerce(left, right);
|
||||
</pre></blockquote>
|
||||
|
||||
for all cases that you don't want to handle yourself.
|
||||
|
||||
<h3><a name="ternary_pow">The Ternary <code>pow()</code> Operator</a></h3>
|
||||
|
||||
<p>
|
||||
In addition to the usual binary <code>pow(x, y)</code> operator (meaning
|
||||
<i>x<sup>y</sup></i>), Python also provides a ternary variant that implements
|
||||
<i>x<sup>y</sup> <b>mod</b> z</i>, presumably using a more efficient algorithm than
|
||||
concatenation of power and modulo operators. Automatic operator wrapping
|
||||
can only be used with the binary variant. Ternary <code>pow()</code> must
|
||||
always be wrapped manually. For a homgeneous ternary <code>pow()</code>,
|
||||
this is done as usual:
|
||||
|
||||
<blockquote><pre>
|
||||
BigNum power(BigNum const& first, BigNum const& second, BigNum const& modulus);
|
||||
typedef BigNum (ternary_function1)(const BigNum&, const BigNum&, const BigNum&);
|
||||
...
|
||||
bignum_class.def((ternary_function1)&power, "__pow__");
|
||||
</pre></blockquote>
|
||||
|
||||
If you want to support this function with non-uniform argument
|
||||
types, wrapping is a little more involved. Suppose you have to wrap:
|
||||
|
||||
<blockquote><pre>
|
||||
BigNum power(BigNum const& first, int second, int modulus);
|
||||
BigNum power(int first, BigNum const& second, int modulus);
|
||||
BigNum power(int first, int second, BigNum const& modulus);
|
||||
</pre></blockquote>
|
||||
|
||||
The first variant can be wrapped as usual:
|
||||
|
||||
<blockquote><pre>
|
||||
typedef BigNum (ternary_function2)(const BigNum&, int, int);
|
||||
bignum_class.def((ternary_function2)&power, "__pow__");
|
||||
</pre></blockquote>
|
||||
|
||||
In the second variant, however, <code>BigNum</code> appears only as second
|
||||
argument, and in the last one it's the third argument. These functions
|
||||
must be presented to Boost.Python such that that the <code>BigNum</code>
|
||||
argument appears in first position:
|
||||
|
||||
<blockquote><pre>
|
||||
BigNum rpower(BigNum const& second, int first, int modulus)
|
||||
{
|
||||
return power(first, second, modulus);
|
||||
}
|
||||
|
||||
BigNum rrpower(BigNum const& modulus, int first, int second)
|
||||
{
|
||||
return power(first, second, modulus);
|
||||
}
|
||||
</pre></blockquote>
|
||||
|
||||
<p>These functions must be wrapped under the names "__rpow__" and "__rrpow__"
|
||||
respectively:
|
||||
|
||||
<blockquote><pre>
|
||||
bignum_class.def((ternary_function2)&rpower, "__rpow__");
|
||||
bignum_class.def((ternary_function2)&rrpower, "__rrpow__");
|
||||
</pre></blockquote>
|
||||
|
||||
Note that "__rrpow__" is an extension not present in plain Python.
|
||||
|
||||
<h2><a name="numeric_table">Table of Automatically Wrapped Methods</a></h2>
|
||||
<p>
|
||||
Boost.Python can automatically wrap the following <a href=
|
||||
"http://www.python.org/doc/current/ref/specialnames.html">
|
||||
special methods</a>:
|
||||
|
||||
<p>
|
||||
<table summary="special numeric methods" cellpadding="5" border="1"
|
||||
width="100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<b>Python Operator Name</b>
|
||||
<td align="center">
|
||||
<b>Python Expression</b>
|
||||
<td align="center">
|
||||
<b>C++ Operator Id</b>
|
||||
<td align="center">
|
||||
<b>C++ Expression Used For Automatic Wrapping</b><br>
|
||||
with <code>cpp_left = from_python(left,
|
||||
type<Left>())</code>,<br>
|
||||
<code>cpp_right = from_python(right,
|
||||
type<Right>())</code>,<br>
|
||||
and <code>cpp_oper = from_python(oper, type<Oper>())</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__add__, __radd__</code>
|
||||
<td>
|
||||
<code>left + right</code>
|
||||
<td>
|
||||
<code>op_add</code>
|
||||
<td>
|
||||
<code>cpp_left + cpp_right</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__sub__, __rsub__</code>
|
||||
<td>
|
||||
<code>left - right</code>
|
||||
<td>
|
||||
<code>op_sub</code>
|
||||
<td>
|
||||
<code>cpp_left - cpp_right</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__mul__, __rmul__</code>
|
||||
<td>
|
||||
<code>left * right</code>
|
||||
<td>
|
||||
<code>op_mul</code>
|
||||
<td>
|
||||
<code>cpp_left * cpp_right</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__div__, __rdiv__</code>
|
||||
<td>
|
||||
<code>left / right</code>
|
||||
<td>
|
||||
<code>op_div</code>
|
||||
<td>
|
||||
<code>cpp_left / cpp_right</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__mod__, __rmod__</code>
|
||||
<td>
|
||||
<code>left % right</code>
|
||||
<td>
|
||||
<code>op_mod</code>
|
||||
<td>
|
||||
<code>cpp_left % cpp_right</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__divmod__, __rdivmod__</code>
|
||||
<td>
|
||||
<code>(quotient, remainder)<br>
|
||||
= divmod(left, right)</code>
|
||||
<td>
|
||||
<code>op_divmod</code>
|
||||
<td>
|
||||
<code>cpp_left / cpp_right</code>
|
||||
<br><code>cpp_left % cpp_right</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__pow__, __rpow__</code>
|
||||
<td>
|
||||
<code>pow(left, right)</code><br>
|
||||
(binary power)
|
||||
<td>
|
||||
<code>op_pow</code>
|
||||
<td>
|
||||
<code>pow(cpp_left, cpp_right)</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__rrpow__</code>
|
||||
<td>
|
||||
<code>pow(left, right, modulo)</code><br>
|
||||
(ternary power modulo)
|
||||
<td colspan="2">
|
||||
no automatic wrapping, <a href="#ternary_pow">special treatment</a>
|
||||
required
|
||||
<tr>
|
||||
<td>
|
||||
<code>__lshift__, __rlshift__</code>
|
||||
<td>
|
||||
<code>left << right</code>
|
||||
<td>
|
||||
<code>op_lshift</code>
|
||||
<td>
|
||||
<code>cpp_left << cpp_right</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__rshift__, __rrshift__</code>
|
||||
<td>
|
||||
<code>left >> right</code>
|
||||
<td>
|
||||
<code>op_rshift</code>
|
||||
<td>
|
||||
<code>cpp_left >> cpp_right</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__and__, __rand__</code>
|
||||
<td>
|
||||
<code>left & right</code>
|
||||
<td>
|
||||
<code>op_and</code>
|
||||
<td>
|
||||
<code>cpp_left & cpp_right</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__xor__, __rxor__</code>
|
||||
<td>
|
||||
<code>left ^ right</code>
|
||||
<td>
|
||||
<code>op_xor</code>
|
||||
<td>
|
||||
<code>cpp_left ^ cpp_right</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__or__, __ror__</code>
|
||||
<td>
|
||||
<code>left | right</code>
|
||||
<td>
|
||||
<code>op_or</code>
|
||||
<td>
|
||||
<code>cpp_left | cpp_right</code>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<code>__cmp__, __rcmp__</code>
|
||||
<td>
|
||||
<code>cmp(left, right)</code><br>
|
||||
<code>left < right</code><br>
|
||||
<code>left <= right</code><br>
|
||||
<code>left > right</code><br>
|
||||
<code>left >= right</code><br>
|
||||
<code>left == right</code><br>
|
||||
<code>left != right</code>
|
||||
<td>
|
||||
<code>op_cmp</code>
|
||||
<td>
|
||||
<code>cpp_left < cpp_right </code>
|
||||
<br><code>cpp_right < cpp_left</code>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<code>__neg__</code>
|
||||
<td>
|
||||
<code>-oper </code> (unary negation)
|
||||
<td>
|
||||
<code>op_neg</code>
|
||||
<td>
|
||||
<code>-cpp_oper</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__pos__</code>
|
||||
<td>
|
||||
<code>+oper </code> (identity)
|
||||
<td>
|
||||
<code>op_pos</code>
|
||||
<td>
|
||||
<code>+cpp_oper</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__abs__</code>
|
||||
<td>
|
||||
<code>abs(oper) </code> (absolute value)
|
||||
<td>
|
||||
<code>op_abs</code>
|
||||
<td>
|
||||
<code>abs(cpp_oper)</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__invert__</code>
|
||||
<td>
|
||||
<code>~oper </code> (bitwise inversion)
|
||||
<td>
|
||||
<code>op_invert</code>
|
||||
<td>
|
||||
<code>~cpp_oper</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__int__</code>
|
||||
<td>
|
||||
<code>int(oper) </code> (integer conversion)
|
||||
<td>
|
||||
<code>op_int</code>
|
||||
<td>
|
||||
<code>long(cpp_oper)</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__long__</code>
|
||||
<td>
|
||||
<code>long(oper) </code><br>
|
||||
(infinite precision integer conversion)
|
||||
<td>
|
||||
<code>op_long</code>
|
||||
<td>
|
||||
<code>PyLong_FromLong(cpp_oper)</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__float__</code>
|
||||
<td>
|
||||
<code>float(oper) </code> (float conversion)
|
||||
<td>
|
||||
<code>op_float</code>
|
||||
<td>
|
||||
<code>double(cpp_oper)</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__str__</code>
|
||||
<td>
|
||||
<code>str(oper) </code> (string conversion)
|
||||
<td>
|
||||
<code>op_str</code>
|
||||
<td>
|
||||
<code>std::ostringstream s; s << oper;</code>
|
||||
<tr>
|
||||
<td>
|
||||
<code>__coerce__</code>
|
||||
<td>
|
||||
<code>coerce(left, right)</code>
|
||||
<td colspan="2">
|
||||
usually defined automatically, otherwise <a href="#coercion">
|
||||
special treatment</a> required
|
||||
</table>
|
||||
|
||||
<h2><a name="sequence_and_mapping">Sequence and Mapping Operators</a></h2>
|
||||
|
||||
<p>
|
||||
Sequence and mapping operators let wrapped objects behave in accordance
|
||||
to Python's iteration and access protocols. These protocols differ
|
||||
considerably from the ones found in C++. For example, Python's typical
|
||||
iteration idiom looks like
|
||||
|
||||
<blockquote><pre>
|
||||
for i in S:
|
||||
</pre></blockquote>
|
||||
|
||||
while in C++ one writes
|
||||
|
||||
<blockquote><pre>
|
||||
for (iterator i = S.begin(), end = S.end(); i != end; ++i)
|
||||
</pre></blockquote>
|
||||
|
||||
<p>One could try to wrap C++ iterators in order to carry the C++ idiom into
|
||||
Python. However, this does not work very well because
|
||||
|
||||
<ol>
|
||||
<li>It leads to
|
||||
non-uniform Python code (wrapped sequences support a usage different from
|
||||
Python built-in sequences) and
|
||||
|
||||
<li>Iterators (e.g. <code>std::vector::iterator</code>) are often implemented as plain C++
|
||||
pointers which are <a href="pointers.html#problem">problematic</a> for any automatic
|
||||
wrapping system.
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
It is a better idea to support the standard <a
|
||||
href="http://www.python.org/doc/current/ref/sequence-types.html">Python
|
||||
sequence and mapping protocols</a> for your wrapped containers. These
|
||||
operators have to be wrapped manually because there are no corresponding
|
||||
C++ operators that could be used for automatic wrapping. The Python
|
||||
documentation lists the relevant <a href=
|
||||
"http://www.python.org/doc/current/ref/sequence-types.html">
|
||||
container operators</a>. In particular, expose __getitem__, __setitem__
|
||||
and remember to raise the appropriate Python exceptions
|
||||
(<code>PyExc_IndexError</code> for sequences,
|
||||
<code>PyExc_KeyError</code> for mappings) when the requested item is not
|
||||
present.
|
||||
|
||||
<p>
|
||||
In the following example, we expose <code>std::map<std::size_t,std::string></code>:
|
||||
<blockquote>
|
||||
<pre>
|
||||
typedef std::map<std::size_t, std::string> StringMap;
|
||||
|
||||
// A helper function for dealing with errors. Throw a Python exception
|
||||
// if p == m.end().
|
||||
void throw_key_error_if_end(
|
||||
const StringMap& m,
|
||||
StringMap::const_iterator p,
|
||||
std::size_t key)
|
||||
{
|
||||
if (p == m.end())
|
||||
{
|
||||
PyErr_SetObject(PyExc_KeyError, boost::python::converters::to_python(key));
|
||||
throw boost::python::error_already_set();
|
||||
}
|
||||
}
|
||||
|
||||
// Define some simple wrapper functions which match the Python protocol
|
||||
// for __getitem__, __setitem__, and __delitem__. Just as in Python, a
|
||||
// free function with a ``self'' first parameter makes a fine class method.
|
||||
|
||||
const std::string& get_item(const StringMap& self, std::size_t key)
|
||||
{
|
||||
const StringMap::const_iterator p = self.find(key);
|
||||
throw_key_error_if_end(self, p, key);
|
||||
return p->second;
|
||||
}
|
||||
|
||||
// Sets the item corresponding to key in the map.
|
||||
void StringMapPythonClass::set_item(StringMap& self, std::size_t key, const std::string& value)
|
||||
{
|
||||
self[key] = value;
|
||||
}
|
||||
|
||||
// Deletes the item corresponding to key from the map.
|
||||
void StringMapPythonClass::del_item(StringMap& self, std::size_t key)
|
||||
{
|
||||
const StringMap::iterator p = self.find(key);
|
||||
throw_key_error_if_end(self, p, key);
|
||||
self.erase(p);
|
||||
}
|
||||
|
||||
class_builder<StringMap> string_map(my_module, "StringMap");
|
||||
string_map.def(boost::python::constructor<>());
|
||||
string_map.def(&StringMap::size, "__len__");
|
||||
string_map.def(get_item, "__getitem__");
|
||||
string_map.def(set_item, "__setitem__");
|
||||
string_map.def(del_item, "__delitem__");
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>
|
||||
Then in Python:
|
||||
<blockquote>
|
||||
<pre>
|
||||
>>> m = StringMap()
|
||||
>>> m[1]
|
||||
Traceback (innermost last):
|
||||
File "<stdin>", line 1, in ?
|
||||
KeyError: 1
|
||||
>>> m[1] = 'hello'
|
||||
>>> m[1]
|
||||
'hello'
|
||||
>>> del m[1]
|
||||
>>> m[1] # prove that it's gone
|
||||
Traceback (innermost last):
|
||||
File "<stdin>", line 1, in ?
|
||||
KeyError: 1
|
||||
>>> del m[2]
|
||||
Traceback (innermost last):
|
||||
File "<stdin>", line 1, in ?
|
||||
KeyError: 2
|
||||
>>> len(m)
|
||||
0
|
||||
>>> m[0] = 'zero'
|
||||
>>> m[1] = 'one'
|
||||
>>> m[2] = 'two'
|
||||
>>> m[3] = 'three'
|
||||
>>> len(m)
|
||||
4
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h2><a name="getter_setter">Customized Attribute Access</a></h2>
|
||||
|
||||
<p>
|
||||
Just like built-in Python classes, Boost.Python extension classes support <a
|
||||
href="http://www.python.org/doc/current/ref/attribute-access.html">special
|
||||
the usual attribute access methods</a> <code>__getattr__</code>,
|
||||
<code>__setattr__</code>, and <code>__delattr__</code>.
|
||||
Because writing these functions can
|
||||
be tedious in the common case where the attributes being accessed are
|
||||
known statically, Boost.Python checks the special names
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<code>__getattr__<em><name></em>__</code>
|
||||
<li>
|
||||
<code>__setattr__<em><name></em>__</code>
|
||||
<li>
|
||||
<code>__delattr__<em><name></em>__</code>
|
||||
</ul>
|
||||
|
||||
to provide functional access to the attribute <em><name></em>. This
|
||||
facility can be used from C++ or entirely from Python. For example, the
|
||||
following shows how we can implement a ``computed attribute'' in Python:
|
||||
<blockquote>
|
||||
<pre>
|
||||
>>> class Range(AnyBoost.PythonExtensionClass):
|
||||
... def __init__(self, start, end):
|
||||
... self.start = start
|
||||
... self.end = end
|
||||
... def __getattr__length__(self):
|
||||
... return self.end - self.start
|
||||
...
|
||||
>>> x = Range(3, 9)
|
||||
>>> x.length
|
||||
6
|
||||
</pre>
|
||||
</blockquote>
|
||||
<h4>
|
||||
Direct Access to Data Members
|
||||
</h4>
|
||||
<p>
|
||||
Boost.Python uses the special <code>
|
||||
__xxxattr__<em><name></em>__</code> functionality described above
|
||||
to allow direct access to data members through the following special
|
||||
functions on <code>class_builder<></code> and <code>
|
||||
extension_class<></code>:
|
||||
<ul>
|
||||
<li>
|
||||
<code>def_getter(<em>pointer-to-member</em>, <em>name</em>)</code> //
|
||||
read access to the member via attribute <em>name</em>
|
||||
<li>
|
||||
<code>def_setter(<em>pointer-to-member</em>, <em>name</em>)</code> //
|
||||
write access to the member via attribute <em>name</em>
|
||||
<li>
|
||||
<code>def_readonly(<em>pointer-to-member</em>, <em>name</em>)</code>
|
||||
// read-only access to the member via attribute <em>name</em>
|
||||
<li>
|
||||
<code>def_read_write(<em>pointer-to-member</em>, <em>
|
||||
name</em>)</code> // read/write access to the member via attribute
|
||||
<em>name</em>
|
||||
</ul>
|
||||
<p>
|
||||
Note that the first two functions, used alone, may produce surprising
|
||||
behavior. For example, when <code>def_getter()</code> is used, the
|
||||
default functionality for <code>setattr()</code> and <code>
|
||||
delattr()</code> remains in effect, operating on items in the extension
|
||||
instance's name-space (i.e., its <code>__dict__</code>). For that
|
||||
reason, you'll usually want to stick with <code>def_readonly</code> and
|
||||
<code>def_read_write</code>.
|
||||
<p>
|
||||
For example, to expose a <code>std::pair<int,long></code> we
|
||||
might write:
|
||||
<blockquote>
|
||||
<pre>
|
||||
typedef std::pair<int,long> Pil;
|
||||
int first(const Pil& x) { return x.first; }
|
||||
long second(const Pil& x) { return x.second; }
|
||||
...
|
||||
my_module.def(first, "first");
|
||||
my_module.def(second, "second");
|
||||
|
||||
class_builder<Pil> pair_int_long(my_module, "Pair");
|
||||
pair_int_long.def(boost::python::constructor<>());
|
||||
pair_int_long.def(boost::python::constructor<int,long>());
|
||||
pair_int_long.def_read_write(&Pil::first, "first");
|
||||
pair_int_long.def_read_write(&Pil::second, "second");
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>
|
||||
Now your Python class has attributes <code>first</code> and <code>
|
||||
second</code> which, when accessed, actually modify or reflect the
|
||||
values of corresponding data members of the underlying C++ object. Now
|
||||
in Python:
|
||||
<blockquote>
|
||||
<pre>
|
||||
>>> x = Pair(3,5)
|
||||
>>> x.first
|
||||
3
|
||||
>>> x.second
|
||||
5
|
||||
>>> x.second = 8
|
||||
>>> x.second
|
||||
8
|
||||
>>> second(x) # Prove that we're not just changing the instance __dict__
|
||||
8
|
||||
</pre>
|
||||
</blockquote>
|
||||
<h2>
|
||||
<a name="reasons">And what about <code>__complex__</code>?</a>
|
||||
</h2>
|
||||
<p>
|
||||
That, dear reader, is one problem we don't know how to solve. The
|
||||
Python source contains the following fragment, indicating the
|
||||
special-case code really is hardwired:
|
||||
<blockquote>
|
||||
<pre>
|
||||
/* XXX Hack to support classes with __complex__ method */
|
||||
if (PyInstance_Check(r)) { ...
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>
|
||||
Next: <a href="under-the-hood.html">A Peek Under the Hood</a>
|
||||
Previous: <a href="inheritance.html">Inheritance</a>
|
||||
Up: <a href= "index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams and Ullrich Köthe 2000.
|
||||
Permission to copy, use, modify, sell and distribute this document is
|
||||
granted provided this copyright notice appears in all copies. This
|
||||
document is provided ``as is'' without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.
|
||||
<p>
|
||||
Updated: Nov 26, 2000
|
||||
</div>
|
||||
|
||||
74
doc/support.html
Normal file
@@ -0,0 +1,74 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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="../../../boost.png" 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>
|
||||
</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>
|
||||
</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>
|
||||
</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>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2003.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
20
doc/tutorial/doc/Jamfile.v2
Normal file
@@ -0,0 +1,20 @@
|
||||
# Copyright Joel de Guzman 2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
project boost/libs/python/doc/tutorial/doc ;
|
||||
|
||||
import boostbook : boostbook ;
|
||||
using quickbook ;
|
||||
|
||||
path-constant images : html ;
|
||||
|
||||
boostbook tutorial
|
||||
:
|
||||
tutorial.qbk
|
||||
:
|
||||
<xsl:param>boost.root=../../../../../..
|
||||
<xsl:param>boost.libraries=../../../../../../libs/libraries.htm
|
||||
<xsl:param>html.stylesheet=../../../../../../doc/html/boostbook.css
|
||||
<format>pdf:<xsl:param>img.src.path=$(images)/
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/python/doc/tutorial/doc/html
|
||||
;
|
||||
BIN
doc/tutorial/doc/html/images/alert.png
Normal file
|
After Width: | Height: | Size: 603 B |
BIN
doc/tutorial/doc/html/images/home.png
Normal file
|
After Width: | Height: | Size: 358 B |
BIN
doc/tutorial/doc/html/images/jam.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
doc/tutorial/doc/html/images/next.png
Normal file
|
After Width: | Height: | Size: 336 B |
BIN
doc/tutorial/doc/html/images/note.png
Normal file
|
After Width: | Height: | Size: 658 B |
BIN
doc/tutorial/doc/html/images/prev.png
Normal file
|
After Width: | Height: | Size: 334 B |
BIN
doc/tutorial/doc/html/images/python.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
doc/tutorial/doc/html/images/smiley.png
Normal file
|
After Width: | Height: | Size: 867 B |
BIN
doc/tutorial/doc/html/images/tip.png
Normal file
|
After Width: | Height: | Size: 640 B |
BIN
doc/tutorial/doc/html/images/up.png
Normal file
|
After Width: | Height: | Size: 370 B |
151
doc/tutorial/doc/html/index.html
Normal file
@@ -0,0 +1,151 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Chapter 1. python 2.0</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
|
||||
<link rel="start" href="index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="next" href="python/hello.html" title=" Building Hello World">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav"><a accesskey="n" href="python/hello.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a></div>
|
||||
<div class="chapter" lang="en">
|
||||
<div class="titlepage"><div>
|
||||
<div><h2 class="title">
|
||||
<a name="python"></a>Chapter 1. python 1.0</h2></div>
|
||||
<div><div class="author"><h3 class="author">
|
||||
<span class="firstname">Joel</span> <span class="surname">de Guzman</span>
|
||||
</h3></div></div>
|
||||
<div><div class="author"><h3 class="author">
|
||||
<span class="firstname">David</span> <span class="surname">Abrahams</span>
|
||||
</h3></div></div>
|
||||
<div><p class="copyright">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams</p></div>
|
||||
<div><div class="legalnotice">
|
||||
<a name="id457106"></a><p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
http://www.boost.org/LICENSE_1_0.txt </a>)
|
||||
</p>
|
||||
</div></div>
|
||||
</div></div>
|
||||
<div class="toc">
|
||||
<p><b>Table of Contents</b></p>
|
||||
<dl>
|
||||
<dt><span class="section"><a href="index.html#python.quickstart">QuickStart</a></span></dt>
|
||||
<dt><span class="section"><a href="python/hello.html"> Building Hello World</a></span></dt>
|
||||
<dt><span class="section"><a href="python/exposing.html"> Exposing Classes</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="python/exposing.html#python.constructors">Constructors</a></span></dt>
|
||||
<dt><span class="section"><a href="python/exposing.html#python.class_data_members">Class Data Members</a></span></dt>
|
||||
<dt><span class="section"><a href="python/exposing.html#python.class_properties">Class Properties</a></span></dt>
|
||||
<dt><span class="section"><a href="python/exposing.html#python.inheritance">Inheritance</a></span></dt>
|
||||
<dt><span class="section"><a href="python/exposing.html#python.class_virtual_functions">Class Virtual Functions</a></span></dt>
|
||||
<dt><span class="section"><a href="python/exposing.html#python.virtual_functions_with_default_implementations">Virtual Functions with Default Implementations</a></span></dt>
|
||||
<dt><span class="section"><a href="python/exposing.html#python.class_operators_special_functions">Class Operators/Special Functions</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="python/functions.html">Functions</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="python/functions.html#python.call_policies">Call Policies</a></span></dt>
|
||||
<dt><span class="section"><a href="python/functions.html#python.overloading">Overloading</a></span></dt>
|
||||
<dt><span class="section"><a href="python/functions.html#python.default_arguments">Default Arguments</a></span></dt>
|
||||
<dt><span class="section"><a href="python/functions.html#python.auto_overloading">Auto-Overloading</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="python/object.html"> Object Interface</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="python/object.html#python.basic_interface">Basic Interface</a></span></dt>
|
||||
<dt><span class="section"><a href="python/object.html#python.derived_object_types">Derived Object types</a></span></dt>
|
||||
<dt><span class="section"><a href="python/object.html#python.extracting_c___objects">Extracting C++ objects</a></span></dt>
|
||||
<dt><span class="section"><a href="python/object.html#python.enums">Enums</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="python/embedding.html">Embedding</a></span></dt>
|
||||
<dd><dl><dt><span class="section"><a href="python/embedding.html#python.using_the_interpreter">Using the interpreter</a></span></dt></dl></dd>
|
||||
<dt><span class="section"><a href="python/iterators.html">Iterators</a></span></dt>
|
||||
<dt><span class="section"><a href="python/exception.html"> Exception Translation</a></span></dt>
|
||||
<dt><span class="section"><a href="python/techniques.html"> General Techniques</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="python/techniques.html#python.creating_packages">Creating Packages</a></span></dt>
|
||||
<dt><span class="section"><a href="python/techniques.html#python.extending_wrapped_objects_in_python">Extending Wrapped Objects in Python</a></span></dt>
|
||||
<dt><span class="section"><a href="python/techniques.html#python.reducing_compiling_time">Reducing Compiling Time</a></span></dt>
|
||||
</dl></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.quickstart"></a>QuickStart</h2></div></div></div>
|
||||
<p>
|
||||
The Boost Python Library is a framework for interfacing Python and C++. It
|
||||
allows you to quickly and seamlessly expose C++ classes functions and objects
|
||||
to Python, and vice-versa, using no special tools -- just your C++ compiler.
|
||||
It is designed to wrap C++ interfaces non-intrusively, so that you should not
|
||||
have to change the C++ code at all in order to wrap it, making Boost.Python
|
||||
ideal for exposing 3rd-party libraries to Python. The library's use of advanced
|
||||
metaprogramming techniques simplifies its syntax for users, so that wrapping
|
||||
code takes on the look of a kind of declarative interface definition language
|
||||
(IDL).
|
||||
</p>
|
||||
<a name="quickstart.hello_world"></a><h2>
|
||||
<a name="id386707"></a>
|
||||
Hello World
|
||||
</h2>
|
||||
<p>
|
||||
Following C/C++ tradition, let's start with the "hello, world". A
|
||||
C++ Function:
|
||||
</p>
|
||||
<pre class="programlisting"><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">"hello, world"</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
can be exposed to Python by writing a Boost.Python wrapper:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||||
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello_ext</span><span class="special">)</span>
|
||||
<span class="special">{</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">def</span><span class="special">(</span><span class="string">"greet"</span><span class="special">,</span> <span class="identifier">greet</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
That's it. We're done. We can now build this as a shared library. The resulting
|
||||
DLL is now visible to Python. Here's a sample Python session:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello_ext</span>
|
||||
<span class="special">>>></span> <span class="keyword">print</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
|
||||
<span class="identifier">hello</span><span class="special">,</span> <span class="identifier">world</span>
|
||||
</pre>
|
||||
<p>
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote">
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
<span class="emphasis"><em><span class="bold"><b>Next stop... Building your Hello World
|
||||
module from start to finish...</b></span></em></span>
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
</blockquote></div>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><p><small>Last revised: November 22, 2008 at 03:24:11 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav"><a accesskey="n" href="python/hello.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a></div>
|
||||
</body>
|
||||
</html>
|
||||
277
doc/tutorial/doc/html/python/embedding.html
Normal file
@@ -0,0 +1,277 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Embedding</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
|
||||
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="prev" href="object.html" title=" Object Interface">
|
||||
<link rel="next" href="iterators.html" title="Iterators">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="object.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.embedding"></a>Embedding</h2></div></div></div>
|
||||
<div class="toc"><dl><dt><span class="section"><a href="embedding.html#python.using_the_interpreter">Using the interpreter</a></span></dt></dl></div>
|
||||
<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 <span class="emphasis"><em>embed</em></span> 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" target="_top">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... <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span>
|
||||
</p>
|
||||
<a name="embedding.building_embedded_programs"></a><h2>
|
||||
<a name="id472330"></a>
|
||||
Building embedded programs
|
||||
</h2>
|
||||
<p>
|
||||
To be able to embed python into your programs, you have to link to both Boost.Python's
|
||||
as well as Python's own runtime library.
|
||||
</p>
|
||||
<p>
|
||||
Boost.Python's library comes in two variants. Both are located in Boost's
|
||||
<tt class="literal">/libs/python/build/bin-stage</tt> subdirectory. On Windows, the
|
||||
variants are called <tt class="literal">boost_python.lib</tt> (for release builds)
|
||||
and <tt class="literal">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" target="_top">Building and Testing</a> on how to do this.
|
||||
</p>
|
||||
<p>
|
||||
Python's library can be found in the <tt class="literal">/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 class="literal">/include</tt> subdirectory has to be added
|
||||
to your include path.
|
||||
</p>
|
||||
<p>
|
||||
In a Jamfile, all the above boils down to:
|
||||
</p>
|
||||
<pre class="programlisting">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) ;
|
||||
</pre>
|
||||
<a name="embedding.getting_started"></a><h2>
|
||||
<a name="id472435"></a>
|
||||
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>
|
||||
<div class="orderedlist"><ol type="1">
|
||||
<li>
|
||||
#include <tt class="literal"><boost/python.hpp></tt>
|
||||
</li>
|
||||
<li>
|
||||
Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-652" target="_top">Py_Initialize</a>()
|
||||
to start the interpreter and create the <tt class="literal"><span class="underline">_main</span>_</tt>
|
||||
module.
|
||||
</li>
|
||||
<li>
|
||||
Call other Python C API routines to use the interpreter.
|
||||
</li>
|
||||
</ol></div>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top"><p>
|
||||
<span class="bold"><b>Note that at this time you must not call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656" target="_top">Py_Finalize</a>()
|
||||
to stop the interpreter. This may be fixed in a future version of boost.python.</b></span>
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
(Of course, there can be other C++ code between all of these steps.)
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote">
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
<span class="emphasis"><em><span class="bold"><b>Now that we can embed the interpreter in
|
||||
our programs, lets see how to put it to use...</b></span></em></span>
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
</blockquote></div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.using_the_interpreter"></a>Using the interpreter</h3></div></div></div>
|
||||
<p>
|
||||
As you probably already know, objects in Python are reference-counted. Naturally,
|
||||
the <tt class="literal">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/c-api/refcounting.html" target="_top">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" target="_top">handle</a>
|
||||
and <a href="../../../../v2/object.html" target="_top">object</a> class templates to
|
||||
automate the process.
|
||||
</p>
|
||||
<a name="using_the_interpreter.running_python_code"></a><h2>
|
||||
<a name="id472601"></a>
|
||||
Running Python code
|
||||
</h2>
|
||||
<p>
|
||||
Boost.python provides three related functions to run Python code from C++.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">eval</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">expression</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
|
||||
<span class="identifier">object</span> <span class="identifier">exec</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">code</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
|
||||
<span class="identifier">object</span> <span class="identifier">exec_file</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">filename</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">globals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">(),</span> <span class="identifier">object</span> <span class="identifier">locals</span> <span class="special">=</span> <span class="identifier">object</span><span class="special">())</span>
|
||||
</pre>
|
||||
<p>
|
||||
eval evaluates the given expression and returns the resulting value. exec
|
||||
executes the given code (typically a set of statements) returning the result,
|
||||
and exec_file executes the code contained in the given file.
|
||||
</p>
|
||||
<p>
|
||||
The <tt class="literal">globals</tt> and <tt class="literal">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 class="literal"><span class="underline">_main</span>_</tt>
|
||||
module for both parameters.
|
||||
</p>
|
||||
<p>
|
||||
Boost.python provides a function to import a module:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">import</span><span class="special">(</span><span class="identifier">str</span> <span class="identifier">name</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
import imports a python module (potentially loading it into the running process
|
||||
first), and returns it.
|
||||
</p>
|
||||
<p>
|
||||
Let's import the <tt class="literal"><span class="underline">_main</span>_</tt>
|
||||
module and run some Python code in its namespace:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
|
||||
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
|
||||
|
||||
<span class="identifier">object</span> <span class="identifier">ignored</span> <span class="special">=</span> <span class="identifier">exec</span><span class="special">(</span><span class="string">"hello = file('hello.txt', 'w')\n"</span>
|
||||
<span class="string">"hello.write('Hello world!')\n"</span>
|
||||
<span class="string">"hello.close()"</span><span class="special">,</span>
|
||||
<span class="identifier">main_namespace</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
This should create a file called 'hello.txt' in the current directory containing
|
||||
a phrase that is well-known in programming circles.
|
||||
</p>
|
||||
<a name="using_the_interpreter.manipulating_python_objects"></a><h2>
|
||||
<a name="id473185"></a>
|
||||
Manipulating Python objects
|
||||
</h2>
|
||||
<p>
|
||||
Often we'd like to have a class to manipulate Python objects. But we have
|
||||
already seen such a class above, and in the <a href="object.html" target="_top">previous
|
||||
section</a>: the aptly named <tt class="literal">object</tt> class and its
|
||||
derivatives. We've already seen that they can be constructed from a <tt class="literal">handle</tt>.
|
||||
The following examples should further illustrate this fact:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">main_module</span> <span class="special">=</span> <span class="identifier">import</span><span class="special">(</span><span class="string">"__main__"</span><span class="special">);</span>
|
||||
<span class="identifier">object</span> <span class="identifier">main_namespace</span> <span class="special">=</span> <span class="identifier">main_module</span><span class="special">.</span><span class="identifier">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">);</span>
|
||||
<span class="identifier">object</span> <span class="identifier">ignored</span> <span class="special">=</span> <span class="identifier">exec</span><span class="special">(</span><span class="string">"result = 5 ** 2"</span><span class="special">,</span> <span class="identifier">main_namespace</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"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">main_namespace</span><span class="special">[</span><span class="string">"result"</span><span class="special">]);</span>
|
||||
</pre>
|
||||
<p>
|
||||
Here we create a dictionary object for the <tt class="literal"><span class="underline">_main</span>_</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 use eval instead, which returns the result directly:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">eval</span><span class="special">(</span><span class="string">"5 ** 2"</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"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">result</span><span class="special">);</span>
|
||||
</pre>
|
||||
<a name="using_the_interpreter.exception_handling"></a><h2>
|
||||
<a name="id473554"></a>
|
||||
Exception handling
|
||||
</h2>
|
||||
<p>
|
||||
If an exception occurs in the evaluation of the python expression, <a href="../../../../v2/errors.html#error_already_set-spec" target="_top">error_already_set</a>
|
||||
is thrown:
|
||||
</p>
|
||||
<pre class="programlisting"><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">eval</span><span class="special">(</span><span class="string">"5/0"</span><span class="special">);</span>
|
||||
<span class="comment">// execution will never get here:
|
||||
</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"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">result</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// handle the exception in some way
|
||||
</span><span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
The <tt class="literal">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" target="_top">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" target="_top">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" target="_top">standard
|
||||
exceptions</a>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">catch</span><span class="special">(</span><span class="identifier">error_already_set</span> <span class="keyword">const</span> <span class="special">&)</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="special">{</span>
|
||||
<span class="comment">// handle ZeroDivisionError specially
|
||||
</span> <span class="special">}</span>
|
||||
<span class="keyword">else</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// print all other errors to stderr
|
||||
</span> <span class="identifier">PyErr_Print</span><span class="special">();</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<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" target="_top">here</a>.)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
http://www.boost.org/LICENSE_1_0.txt </a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="object.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
63
doc/tutorial/doc/html/python/exception.html
Normal file
@@ -0,0 +1,63 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title> Exception Translation</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
|
||||
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="prev" href="iterators.html" title="Iterators">
|
||||
<link rel="next" href="techniques.html" title=" General Techniques">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="iterators.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="techniques.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.exception"></a> Exception Translation</h2></div></div></div>
|
||||
<p>
|
||||
All C++ exceptions must be caught at the boundary with Python code. This boundary
|
||||
is the point where C++ meets Python. Boost.Python provides a default exception
|
||||
handler that translates selected standard exceptions, then gives up:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">raise</span> <span class="identifier">RuntimeError</span><span class="special">,</span> <span class="string">'unidentifiable C++ Exception'</span>
|
||||
</pre>
|
||||
<p>
|
||||
Users may provide custom translation. Here's an example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">struct</span> <span class="identifier">PodBayDoorException</span><span class="special">;</span>
|
||||
<span class="identifier">void</span> <span class="identifier">translator</span><span class="special">(</span><span class="identifier">PodBayDoorException</span> <span class="identifier">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</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">"I'm sorry Dave..."</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">register_exception_translator</span><span class="special"><</span>
|
||||
<span class="identifier">PodBayDoorException</span><span class="special">>(</span><span class="identifier">translator</span><span class="special">);</span>
|
||||
<span class="special">...</span>
|
||||
</pre>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
http://www.boost.org/LICENSE_1_0.txt </a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="iterators.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="techniques.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
605
doc/tutorial/doc/html/python/exposing.html
Normal file
@@ -0,0 +1,605 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title> Exposing Classes</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
|
||||
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="prev" href="hello.html" title=" Building Hello World">
|
||||
<link rel="next" href="functions.html" title="Functions">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="hello.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="functions.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.exposing"></a> Exposing Classes</h2></div></div></div>
|
||||
<div class="toc"><dl>
|
||||
<dt><span class="section"><a href="exposing.html#python.constructors">Constructors</a></span></dt>
|
||||
<dt><span class="section"><a href="exposing.html#python.class_data_members">Class Data Members</a></span></dt>
|
||||
<dt><span class="section"><a href="exposing.html#python.class_properties">Class Properties</a></span></dt>
|
||||
<dt><span class="section"><a href="exposing.html#python.inheritance">Inheritance</a></span></dt>
|
||||
<dt><span class="section"><a href="exposing.html#python.class_virtual_functions">Class Virtual Functions</a></span></dt>
|
||||
<dt><span class="section"><a href="exposing.html#python.virtual_functions_with_default_implementations">Virtual Functions with Default Implementations</a></span></dt>
|
||||
<dt><span class="section"><a href="exposing.html#python.class_operators_special_functions">Class Operators/Special Functions</a></span></dt>
|
||||
</dl></div>
|
||||
<p>
|
||||
Now let's expose a C++ class to Python.
|
||||
</p>
|
||||
<p>
|
||||
Consider a C++ class/struct that we want to expose to Python:
|
||||
</p>
|
||||
<pre class="programlisting"><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">-></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">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>
|
||||
<p>
|
||||
We can expose this to Python by writing a corresponding Boost.Python C++ Wrapper:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></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"><</span><span class="identifier">World</span><span class="special">>(</span><span class="string">"World"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"greet"</span><span class="special">,</span> <span class="special">&</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">"set"</span><span class="special">,</span> <span class="special">&</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>
|
||||
</pre>
|
||||
<p>
|
||||
Here, we wrote a C++ class wrapper that exposes the member functions <tt class="literal">greet</tt>
|
||||
and <tt class="literal">set</tt>. Now, after building our module as a shared library,
|
||||
we may use our class <tt class="literal">World</tt> in Python. Here's a sample Python
|
||||
session:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">hello</span>
|
||||
<span class="special">>>></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">>>></span> <span class="identifier">planet</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span><span class="string">'howdy'</span><span class="special">)</span>
|
||||
<span class="special">>>></span> <span class="identifier">planet</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
|
||||
<span class="string">'howdy'</span>
|
||||
</pre>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.constructors"></a>Constructors</h3></div></div></div>
|
||||
<p>
|
||||
Our previous example didn't have any explicit constructors. Since <tt class="literal">World</tt>
|
||||
is declared as a plain struct, it has an implicit default constructor. Boost.Python
|
||||
exposes the default constructor by default, which is why we were able to
|
||||
write
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></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>
|
||||
</pre>
|
||||
<p>
|
||||
We may wish to wrap a class with a non-default constructor. Let us build
|
||||
on our previous example:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><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">-></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">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>
|
||||
<p>
|
||||
This time <tt class="literal">World</tt> has no default constructor; our previous
|
||||
wrapping code would fail to compile when the library tried to expose it.
|
||||
We have to tell <tt class="literal">class_<World></tt> about the constructor
|
||||
we want to expose instead.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></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"><</span><span class="identifier">World</span><span class="special">>(</span><span class="string">"World"</span><span class="special">,</span> <span class="identifier">init</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="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"greet"</span><span class="special">,</span> <span class="special">&</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">"set"</span><span class="special">,</span> <span class="special">&</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>
|
||||
</pre>
|
||||
<p>
|
||||
<tt class="literal">init<std::string>()</tt> exposes the constructor taking
|
||||
in a <tt class="literal">std::string</tt> (in Python, constructors are spelled
|
||||
"<tt class="literal">"<span class="underline">_init</span>_"</tt>").
|
||||
</p>
|
||||
<p>
|
||||
We can expose additional constructors by passing more <tt class="literal">init<...></tt>s
|
||||
to the <tt class="literal">def()</tt> member function. Say for example we have
|
||||
another World constructor taking in two doubles:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">World</span><span class="special">>(</span><span class="string">"World"</span><span class="special">,</span> <span class="identifier">init</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="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special"><</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">>())</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"greet"</span><span class="special">,</span> <span class="special">&</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">"set"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">World</span><span class="special">::</span><span class="identifier">set</span><span class="special">)</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
On the other hand, if we do not wish to expose any constructors at all, we
|
||||
may use <tt class="literal">no_init</tt> instead:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Abstract</span><span class="special">>(</span><span class="string">"Abstract"</span><span class="special">,</span> <span class="identifier">no_init</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
This actually adds an <tt class="literal"><span class="underline">_init</span>_</tt>
|
||||
method which always raises a Python RuntimeError exception.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.class_data_members"></a>Class Data Members</h3></div></div></div>
|
||||
<p>
|
||||
Data members may also be exposed to Python so that they can be accessed as
|
||||
attributes of the corresponding Python class. Each data member that we wish
|
||||
to be exposed may be regarded as <span class="bold"><b>read-only</b></span>
|
||||
or <span class="bold"><b>read-write</b></span>. Consider this class <tt class="literal">Var</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><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">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>
|
||||
<p>
|
||||
Our C++ <tt class="literal">Var</tt> class and its data members can be exposed
|
||||
to Python:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Var</span><span class="special">>(</span><span class="string">"Var"</span><span class="special">,</span> <span class="identifier">init</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="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"name"</span><span class="special">,</span> <span class="special">&</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">"value"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Var</span><span class="special">::</span><span class="identifier">value</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
Then, in Python, assuming we have placed our Var class inside the namespace
|
||||
hello as we did before:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></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="string">'pi'</span><span class="special">)</span>
|
||||
<span class="special">>>></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">>>></span> <span class="keyword">print</span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span><span class="special">,</span> <span class="string">'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="keyword">is</span> <span class="identifier">around</span> <span class="number">3.14</span>
|
||||
</pre>
|
||||
<p>
|
||||
Note that <tt class="literal">name</tt> is exposed as <span class="bold"><b>read-only</b></span>
|
||||
while <tt class="literal">value</tt> is exposed as <span class="bold"><b>read-write</b></span>.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">name</span> <span class="special">=</span> <span class="string">'e'</span> <span class="comment"># can't change name
|
||||
</span><span class="identifier">Traceback</span> <span class="special">(</span><span class="identifier">most</span> <span class="identifier">recent</span> <span class="identifier">call</span> <span class="identifier">last</span><span class="special">):</span>
|
||||
<span class="identifier">File</span> <span class="string">"<stdin>"</span><span class="special">,</span> <span class="identifier">line</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">in</span> #
|
||||
<span class="identifier">AttributeError</span><span class="special">:</span> <span class="identifier">can</span>#<span class="identifier">t</span> <span class="identifier">set</span> <span class="identifier">attribute</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.class_properties"></a>Class Properties</h3></div></div></div>
|
||||
<p>
|
||||
In C++, classes with public data members are usually frowned upon. Well designed
|
||||
classes that take advantage of encapsulation hide the class' data members.
|
||||
The only way to access the class' data is through access (getter/setter)
|
||||
functions. Access functions expose class properties. Here's an example:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Num</span>
|
||||
<span class="special">{</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>
|
||||
<p>
|
||||
However, in Python attribute access is fine; it doesn't neccessarily break
|
||||
encapsulation to let users handle attributes directly, because the attributes
|
||||
can just be a different syntax for a method call. Wrapping our <tt class="literal">Num</tt>
|
||||
class using Boost.Python:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Num</span><span class="special">>(</span><span class="string">"Num"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</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">"value"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">set</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
And at last, in Python:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">Num</span><span class="special">()</span>
|
||||
<span class="special">>>></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">>>></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">>>></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="comment"># error!
|
||||
</span></pre>
|
||||
<p>
|
||||
Take note that the class property <tt class="literal">rovalue</tt> is exposed as
|
||||
<span class="bold"><b>read-only</b></span> since the <tt class="literal">rovalue</tt>
|
||||
setter member function is not passed in:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">add_property</span><span class="special">(</span><span class="string">"rovalue"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">Num</span><span class="special">::</span><span class="identifier">get</span><span class="special">)</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.inheritance"></a>Inheritance</h3></div></div></div>
|
||||
<p>
|
||||
In the previous examples, we dealt with classes that are not polymorphic.
|
||||
This is not often the case. Much of the time, we will be wrapping polymorphic
|
||||
classes and class hierarchies related by inheritance. We will often have
|
||||
to write Boost.Python wrappers for classes that are derived from abstract
|
||||
base classes.
|
||||
</p>
|
||||
<p>
|
||||
Consider this trivial inheritance structure:
|
||||
</p>
|
||||
<pre class="programlisting"><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>
|
||||
<span class="keyword">struct</span> <span class="identifier">Derived</span> <span class="special">:</span> <span class="identifier">Base</span> <span class="special">{};</span>
|
||||
</pre>
|
||||
<p>
|
||||
And a set of C++ functions operating on <tt class="literal">Base</tt> and <tt class="literal">Derived</tt>
|
||||
object instances:
|
||||
</p>
|
||||
<pre class="programlisting"><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>
|
||||
</pre>
|
||||
<p>
|
||||
We've seen how we can wrap the base class <tt class="literal">Base</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Base</span><span class="special">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Now we can inform Boost.Python of the inheritance relationship between <tt class="literal">Derived</tt>
|
||||
and its base class <tt class="literal">Base</tt>. Thus:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">,</span> <span class="identifier">bases</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span> <span class="special">>(</span><span class="string">"Derived"</span><span class="special">)</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Doing so, we get some things for free:
|
||||
</p>
|
||||
<div class="orderedlist"><ol type="1">
|
||||
<li>
|
||||
Derived automatically inherits all of Base's Python methods (wrapped C++
|
||||
member functions)
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>If</b></span> Base is polymorphic, <tt class="literal">Derived</tt>
|
||||
objects which have been passed to Python via a pointer or reference to
|
||||
<tt class="literal">Base</tt> can be passed where a pointer or reference to
|
||||
<tt class="literal">Derived</tt> is expected.
|
||||
</li>
|
||||
</ol></div>
|
||||
<p>
|
||||
Now, we will expose the C++ free functions <tt class="literal">b</tt> and <tt class="literal">d</tt>
|
||||
and <tt class="literal">factory</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"b"</span><span class="special">,</span> <span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"d"</span><span class="special">,</span> <span class="identifier">d</span><span class="special">);</span>
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
Note that free function <tt class="literal">factory</tt> is being used to generate
|
||||
new instances of class <tt class="literal">Derived</tt>. In such cases, we use
|
||||
<tt class="literal">return_value_policy<manage_new_object></tt> to instruct
|
||||
Python to adopt the pointer to <tt class="literal">Base</tt> and hold the instance
|
||||
in a new Python <tt class="literal">Base</tt> object until the the Python object
|
||||
is destroyed. We will see more of Boost.Python <a href="functions.html#python.call_policies" title="Call Policies">call
|
||||
policies</a> later.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment">// Tell Python to take ownership of factory's result
|
||||
</span><span class="identifier">def</span><span class="special">(</span><span class="string">"factory"</span><span class="special">,</span> <span class="identifier">factory</span><span class="special">,</span>
|
||||
<span class="identifier">return_value_policy</span><span class="special"><</span><span class="identifier">manage_new_object</span><span class="special">>());</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.class_virtual_functions"></a>Class Virtual Functions</h3></div></div></div>
|
||||
<p>
|
||||
In this section, we will learn how to make functions behave polymorphically
|
||||
through virtual functions. Continuing our example, let us add a virtual function
|
||||
to our <tt class="literal">Base</tt> class:
|
||||
</p>
|
||||
<pre class="programlisting"><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>
|
||||
<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>
|
||||
</pre>
|
||||
<p>
|
||||
One of the goals of Boost.Python is to be minimally intrusive on an existing
|
||||
C++ design. In principle, it should be possible to expose the interface for
|
||||
a 3rd party library without changing it. It is not ideal to add anything
|
||||
to our class <tt class="computeroutput"><span class="identifier">Base</span></tt>. Yet, when
|
||||
you have a virtual function that's going to be overridden in Python and called
|
||||
polymorphically <span class="bold"><b>from C++</b></span>, we'll need to
|
||||
add some scaffoldings to make things work properly. What we'll do is write
|
||||
a class wrapper that derives from <tt class="computeroutput"><span class="identifier">Base</span></tt>
|
||||
that will unintrusively hook into the virtual functions so that a Python
|
||||
override may be called:
|
||||
</p>
|
||||
<pre class="programlisting"><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">wrapper</span><span class="special"><</span><span class="identifier">Base</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="keyword">this</span><span class="special">-></span><span class="identifier">get_override</span><span class="special">(</span><span class="string">"f"</span><span class="special">)();</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
Notice too that in addition to inheriting from <tt class="computeroutput"><span class="identifier">Base</span></tt>,
|
||||
we also multiply- inherited <tt class="computeroutput"><span class="identifier">wrapper</span><span class="special"><</span><span class="identifier">Base</span><span class="special">></span></tt> (See <a href="../../../../v2/wrapper.html" target="_top">Wrapper</a>).
|
||||
The <tt class="computeroutput"><span class="identifier">wrapper</span></tt> template makes
|
||||
the job of wrapping classes that are meant to overridden in Python, easier.
|
||||
</p>
|
||||
<div class="sidebar">
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span>
|
||||
</p>
|
||||
<p>
|
||||
If you are using Microsoft Visual C++ 6 or 7, you have to write <tt class="computeroutput"><span class="identifier">f</span></tt> as:
|
||||
</p>
|
||||
<p>
|
||||
<tt class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="keyword">this</span><span class="special">-></span><span class="identifier">get_override</span><span class="special">(</span><span class="string">"f"</span><span class="special">).</span><span class="identifier">ptr</span><span class="special">());</span></tt>.
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
BaseWrap's overridden virtual member function <tt class="computeroutput"><span class="identifier">f</span></tt>
|
||||
in effect calls the corresponding method of the Python object through <tt class="computeroutput"><span class="identifier">get_override</span></tt>.
|
||||
</p>
|
||||
<p>
|
||||
Finally, exposing <tt class="computeroutput"><span class="identifier">Base</span></tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</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">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">pure_virtual</span><span class="special">(&</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">))</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
<tt class="computeroutput"><span class="identifier">pure_virtual</span></tt> signals Boost.Python
|
||||
that the function <tt class="computeroutput"><span class="identifier">f</span></tt> is a
|
||||
pure virtual function.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top">
|
||||
<p>
|
||||
<span class="bold"><b>member function and methods</b></span>
|
||||
</p>
|
||||
<p>
|
||||
Python, like many object oriented languages uses the term <span class="bold"><b>methods</b></span>.
|
||||
Methods correspond roughly to C++'s <span class="bold"><b>member functions</b></span>
|
||||
</p>
|
||||
</td></tr>
|
||||
</table></div>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.virtual_functions_with_default_implementations"></a>Virtual Functions with Default Implementations</h3></div></div></div>
|
||||
<p>
|
||||
We've seen in the previous section how classes with pure virtual functions
|
||||
are wrapped using Boost.Python's <a href="../../../../v2/wrapper.html" target="_top">class
|
||||
wrapper</a> facilities. If we wish to wrap <span class="bold"><b>non</b></span>-pure-virtual
|
||||
functions instead, the mechanism is a bit different.
|
||||
</p>
|
||||
<p>
|
||||
Recall that in the <a href="exposing.html#python.class_virtual_functions" title="Class Virtual Functions">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>
|
||||
<pre class="programlisting"><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>
|
||||
</pre>
|
||||
<p>
|
||||
had a pure virtual function <tt class="literal">f</tt>. If, however, its member
|
||||
function <tt class="literal">f</tt> was not declared as pure virtual:
|
||||
</p>
|
||||
<pre class="programlisting"><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>
|
||||
<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>
|
||||
<p>
|
||||
We wrap it this way:
|
||||
</p>
|
||||
<pre class="programlisting"><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">wrapper</span><span class="special"><</span><span class="identifier">Base</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">if</span> <span class="special">(</span><span class="identifier">override</span> <span class="identifier">f</span> <span class="special">=</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">get_override</span><span class="special">(</span><span class="string">"f"</span><span class="special">))</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">();</span> <span class="comment">// *note*
|
||||
</span> <span class="keyword">return</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="keyword">int</span> <span class="identifier">default_f</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="keyword">this</span><span class="special">-></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="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
Notice how we implemented <tt class="computeroutput"><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">f</span></tt>. Now,
|
||||
we have to check if there is an override for <tt class="computeroutput"><span class="identifier">f</span></tt>.
|
||||
If none, then we call <tt class="computeroutput"><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span><span class="special">()</span></tt>.
|
||||
</p>
|
||||
<div class="sidebar">
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span>
|
||||
</p>
|
||||
<p>
|
||||
If you are using Microsoft Visual C++ 6 or 7, you have to rewrite the line
|
||||
with the <tt class="computeroutput"><span class="special">*</span><span class="identifier">note</span><span class="special">*</span></tt> as:
|
||||
</p>
|
||||
<p>
|
||||
<tt class="computeroutput"><span class="keyword">return</span> <span class="identifier">call</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">ptr</span><span class="special">());</span></tt>.
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
Finally, exposing:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</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">>(</span><span class="string">"Base"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="special">&</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="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">default_f</span><span class="special">)</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Take note that we expose both <tt class="computeroutput"><span class="special">&</span><span class="identifier">Base</span><span class="special">::</span><span class="identifier">f</span></tt> and <tt class="computeroutput"><span class="special">&</span><span class="identifier">BaseWrap</span><span class="special">::</span><span class="identifier">default_f</span></tt>. Boost.Python needs to keep track
|
||||
of 1) the dispatch function <tt class="literal">f</tt> and 2) the forwarding function
|
||||
to its default implementation <tt class="literal">default_f</tt>. There's a special
|
||||
<tt class="literal">def</tt> function for this purpose.
|
||||
</p>
|
||||
<p>
|
||||
In Python, the results would be as expected:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">base</span> <span class="special">=</span> <span class="identifier">Base</span><span class="special">()</span>
|
||||
<span class="special">>>></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="keyword">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">>>></span> <span class="identifier">derived</span> <span class="special">=</span> <span class="identifier">Derived</span><span class="special">()</span>
|
||||
</pre>
|
||||
<p>
|
||||
Calling <tt class="literal">base.f()</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></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>
|
||||
<p>
|
||||
Calling <tt class="literal">derived.f()</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></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>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.class_operators_special_functions"></a>Class Operators/Special Functions</h3></div></div></div>
|
||||
<a name="class_operators_special_functions.python_operators"></a><h2>
|
||||
<a name="id462548"></a>
|
||||
Python Operators
|
||||
</h2>
|
||||
<p>
|
||||
C is well known for the abundance of operators. C++ extends this to the extremes
|
||||
by allowing operator overloading. Boost.Python takes advantage of this and
|
||||
makes it easy to wrap C++ operator-powered classes.
|
||||
</p>
|
||||
<p>
|
||||
Consider a file position class <tt class="literal">FilePos</tt> and a set of operators
|
||||
that take on FilePos instances:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">FilePos</span> <span class="special">{</span> <span class="comment">/*...*/</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">);</span>
|
||||
<span class="keyword">int</span> <span class="keyword">operator</span><span class="special">-(</span><span class="identifier">FilePos</span><span class="special">,</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="special">&</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="special">&</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="keyword">bool</span> <span class="keyword">operator</span><span class="special"><(</span><span class="identifier">FilePos</span><span class="special">,</span> <span class="identifier">FilePos</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
The class and the various operators can be mapped to Python rather easily
|
||||
and intuitively:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">FilePos</span><span class="special">>(</span><span class="string">"FilePos"</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">// __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">// __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"><</span><span class="keyword">int</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="identifier">self</span><span class="special">);</span> <span class="comment">// __lt__
|
||||
</span></pre>
|
||||
<p>
|
||||
The code snippet above is very clear and needs almost no explanation at all.
|
||||
It is virtually the same as the operators' signatures. Just take note that
|
||||
<tt class="literal">self</tt> refers to FilePos object. Also, not every class
|
||||
<tt class="literal">T</tt> that you might need to interact with in an operator
|
||||
expression is (cheaply) default-constructible. You can use <tt class="literal">other<T>()</tt>
|
||||
in place of an actual <tt class="literal">T</tt> instance when writing "self
|
||||
expressions".
|
||||
</p>
|
||||
<a name="class_operators_special_functions.special_methods"></a><h2>
|
||||
<a name="id463302"></a>
|
||||
Special Methods
|
||||
</h2>
|
||||
<p>
|
||||
Python has a few more <span class="emphasis"><em>Special Methods</em></span>. Boost.Python
|
||||
supports all of the standard special method names supported by real Python
|
||||
class instances. A similar set of intuitive interfaces can also be used to
|
||||
wrap C++ functions that correspond to these Python <span class="emphasis"><em>special functions</em></span>.
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">Rational</span>
|
||||
<span class="special">{</span> <span class="keyword">public</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="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">&</span> <span class="keyword">operator</span><span class="special"><<(</span><span class="identifier">ostream</span><span class="special">&,</span><span class="identifier">Rational</span><span class="special">);</span>
|
||||
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Rational</span><span class="special">>(</span><span class="string">"Rational"</span><span class="special">)</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"><</span><span class="identifier">Rational</span><span class="special">>))</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="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Need we say more?
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top"><p>
|
||||
What is the business of <tt class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></tt>? Well, the method <tt class="computeroutput"><span class="identifier">str</span></tt> requires the <tt class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></tt> to do its work (i.e. <tt class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></tt>
|
||||
is used by the method defined by <tt class="computeroutput"><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></tt>.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
http://www.boost.org/LICENSE_1_0.txt </a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="hello.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="functions.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
589
doc/tutorial/doc/html/python/functions.html
Normal file
@@ -0,0 +1,589 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Functions</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
|
||||
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="prev" href="exposing.html" title=" Exposing Classes">
|
||||
<link rel="next" href="object.html" title=" Object Interface">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exposing.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="object.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.functions"></a>Functions</h2></div></div></div>
|
||||
<div class="toc"><dl>
|
||||
<dt><span class="section"><a href="functions.html#python.call_policies">Call Policies</a></span></dt>
|
||||
<dt><span class="section"><a href="functions.html#python.overloading">Overloading</a></span></dt>
|
||||
<dt><span class="section"><a href="functions.html#python.default_arguments">Default Arguments</a></span></dt>
|
||||
<dt><span class="section"><a href="functions.html#python.auto_overloading">Auto-Overloading</a></span></dt>
|
||||
</dl></div>
|
||||
<p>
|
||||
In this chapter, we'll look at Boost.Python powered functions in closer detail.
|
||||
We will see some facilities to make exposing C++ functions to Python safe from
|
||||
potential pifalls such as dangling pointers and references. We will also see
|
||||
facilities that will make it even easier for us to expose C++ functions that
|
||||
take advantage of C++ features such as overloading and default arguments.
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote">
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
<span class="emphasis"><em>Read on...</em></span>
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
</blockquote></div>
|
||||
<p>
|
||||
But before you do, you might want to fire up Python 2.2 or later and type
|
||||
<tt class="literal">>>> import this</tt>.
|
||||
</p>
|
||||
<pre class="programlisting">>>> import this
|
||||
The Zen of Python, by Tim Peters
|
||||
Beautiful is better than ugly.
|
||||
Explicit is better than implicit.
|
||||
Simple is better than complex.
|
||||
Complex is better than complicated.
|
||||
Flat is better than nested.
|
||||
Sparse is better than dense.
|
||||
Readability counts.
|
||||
Special cases aren't special enough to break the rules.
|
||||
Although practicality beats purity.
|
||||
Errors should never pass silently.
|
||||
Unless explicitly silenced.
|
||||
In the face of ambiguity, refuse the temptation to guess.
|
||||
There should be one-- and preferably only one --obvious way to do it
|
||||
Although that way may not be obvious at first unless you're Dutch.
|
||||
Now is better than never.
|
||||
Although never is often better than <span class="bold"><b>right</b></span> now.
|
||||
If the implementation is hard to explain, it's a bad idea.
|
||||
If the implementation is easy to explain, it may be a good idea.
|
||||
Namespaces are one honking great idea -- let's do more of those!
|
||||
</pre>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.call_policies"></a>Call Policies</h3></div></div></div>
|
||||
<p>
|
||||
In C++, we often deal with arguments and return types such as pointers and
|
||||
references. Such primitive types are rather, ummmm, low level and they really
|
||||
don't tell us much. At the very least, we don't know the owner of the pointer
|
||||
or the referenced object. No wonder languages such as Java and Python never
|
||||
deal with such low level entities. In C++, it's usually considered a good
|
||||
practice to use smart pointers which exactly describe ownership semantics.
|
||||
Still, even good C++ interfaces use raw references and pointers sometimes,
|
||||
so Boost.Python must deal with them. To do this, it may need your help. Consider
|
||||
the following C++ function:
|
||||
</p>
|
||||
<pre class="programlisting"><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">y</span><span class="special">,</span> <span class="identifier">Z</span><span class="special">*</span> <span class="identifier">z</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
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>
|
||||
<pre class="programlisting"><span class="special">>>></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="preprocessor"># 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">>>></span> <span class="identifier">del</span> <span class="identifier">y</span>
|
||||
<span class="special">>>></span> <span class="identifier">x</span><span class="special">.</span><span class="identifier">some_method</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
|
||||
</pre>
|
||||
<p>
|
||||
What's the problem?
|
||||
</p>
|
||||
<p>
|
||||
Well, what if f() was implemented as shown below:
|
||||
</p>
|
||||
<pre class="programlisting"><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">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>
|
||||
<p>
|
||||
The problem is that the lifetime of result X& is tied to the lifetime
|
||||
of y, because the f() returns a reference to a member of the y object. This
|
||||
idiom is is not uncommon and perfectly acceptable in the context of C++.
|
||||
However, Python users should not be able to crash the system just by using
|
||||
our C++ interface. In this case deleting y will invalidate the reference
|
||||
to X. We have a dangling reference.
|
||||
</p>
|
||||
<p>
|
||||
Here's what's happening:
|
||||
</p>
|
||||
<div class="orderedlist"><ol type="1">
|
||||
<li>
|
||||
<tt class="literal">f</tt> is called passing in a reference to <tt class="literal">y</tt>
|
||||
and a pointer to <tt class="literal">z</tt>
|
||||
</li>
|
||||
<li>
|
||||
A reference to <tt class="literal">y.x</tt> is returned
|
||||
</li>
|
||||
<li>
|
||||
<tt class="literal">y</tt> is deleted. <tt class="literal">x</tt> is a dangling reference
|
||||
</li>
|
||||
<li>
|
||||
<tt class="literal">x.some_method()</tt> is called
|
||||
</li>
|
||||
<li><span class="bold"><b>BOOM!</b></span></li>
|
||||
</ol></div>
|
||||
<p>
|
||||
We could copy result into a new object:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><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">set</span><span class="special">(</span><span class="number">42</span><span class="special">)</span> <span class="comment"># Result disappears
|
||||
</span><span class="special">>>></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="comment"># No crash, but still bad
|
||||
</span><span class="number">3.14</span>
|
||||
</pre>
|
||||
<p>
|
||||
This is not really our intent of our C++ interface. We've broken our promise
|
||||
that the Python interface should reflect the C++ interface as closely as
|
||||
possible.
|
||||
</p>
|
||||
<p>
|
||||
Our problems do not end there. Suppose Y is implemented as follows:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><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">-></span><span class="identifier">value</span><span class="special">();</span> <span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
Notice that the data member <tt class="literal">z</tt> is held by class Y using
|
||||
a raw pointer. Now we have a potential dangling pointer problem inside Y:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></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="preprocessor"># y</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">z</span>
|
||||
<span class="special">>>></span> <span class="identifier">del</span> <span class="identifier">z</span> <span class="preprocessor"># Kill</span> <span class="identifier">the</span> <span class="identifier">z</span> <span class="identifier">object</span>
|
||||
<span class="special">>>></span> <span class="identifier">y</span><span class="special">.</span><span class="identifier">z_value</span><span class="special">()</span> <span class="preprocessor"># CRASH</span><span class="special">!</span>
|
||||
</pre>
|
||||
<p>
|
||||
For reference, here's the implementation of <tt class="literal">f</tt> again:
|
||||
</p>
|
||||
<pre class="programlisting"><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">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>
|
||||
<p>
|
||||
Here's what's happening:
|
||||
</p>
|
||||
<div class="orderedlist"><ol type="1">
|
||||
<li>
|
||||
<tt class="literal">f</tt> is called passing in a reference to <tt class="literal">y</tt>
|
||||
and a pointer to <tt class="literal">z</tt>
|
||||
</li>
|
||||
<li>
|
||||
A pointer to <tt class="literal">z</tt> is held by <tt class="literal">y</tt>
|
||||
</li>
|
||||
<li>
|
||||
A reference to <tt class="literal">y.x</tt> is returned
|
||||
</li>
|
||||
<li>
|
||||
<tt class="literal">z</tt> is deleted. <tt class="literal">y.z</tt> is a dangling pointer
|
||||
</li>
|
||||
<li>
|
||||
<tt class="literal">y.z_value()</tt> is called
|
||||
</li>
|
||||
<li>
|
||||
<tt class="literal">z->value()</tt> is called
|
||||
</li>
|
||||
<li><span class="bold"><b>BOOM!</b></span></li>
|
||||
</ol></div>
|
||||
<a name="call_policies.call_policies"></a><h2>
|
||||
<a name="id465291"></a>
|
||||
Call Policies
|
||||
</h2>
|
||||
<p>
|
||||
Call Policies may be used in situations such as the example detailed above.
|
||||
In our example, <tt class="literal">return_internal_reference</tt> and <tt class="literal">with_custodian_and_ward</tt>
|
||||
are our friends:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">,</span>
|
||||
<span class="identifier">return_internal_reference</span><span class="special"><</span><span class="number">1</span><span class="special">,</span>
|
||||
<span class="identifier">with_custodian_and_ward</span><span class="special"><</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">></span> <span class="special">>());</span>
|
||||
</pre>
|
||||
<p>
|
||||
What are the <tt class="literal">1</tt> and <tt class="literal">2</tt> parameters, you
|
||||
ask?
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">return_internal_reference</span><span class="special"><</span><span class="number">1</span>
|
||||
</pre>
|
||||
<p>
|
||||
Informs Boost.Python that the first argument, in our case <tt class="literal">Y&
|
||||
y</tt>, is the owner of the returned reference: <tt class="literal">X&</tt>.
|
||||
The "<tt class="literal">1</tt>" simply specifies the first argument.
|
||||
In short: "return an internal reference <tt class="literal">X&</tt> owned
|
||||
by the 1st argument <tt class="literal">Y& y</tt>".
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">with_custodian_and_ward</span><span class="special"><</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">></span>
|
||||
</pre>
|
||||
<p>
|
||||
Informs Boost.Python that the lifetime of the argument indicated by ward
|
||||
(i.e. the 2nd argument: <tt class="literal">Z* z</tt>) is dependent on the lifetime
|
||||
of the argument indicated by custodian (i.e. the 1st argument: <tt class="literal">Y&
|
||||
y</tt>).
|
||||
</p>
|
||||
<p>
|
||||
It is also important to note that we have defined two policies above. Two
|
||||
or more policies can be composed by chaining. Here's the general syntax:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">policy1</span><span class="special"><</span><span class="identifier">args</span><span class="special">...,</span>
|
||||
<span class="identifier">policy2</span><span class="special"><</span><span class="identifier">args</span><span class="special">...,</span>
|
||||
<span class="identifier">policy3</span><span class="special"><</span><span class="identifier">args</span><span class="special">...></span> <span class="special">></span> <span class="special">></span>
|
||||
</pre>
|
||||
<p>
|
||||
Here is the list of predefined call policies. A complete reference detailing
|
||||
these can be found <a href="../../../../v2/reference.html#models_of_call_policies" target="_top">here</a>.
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
<span class="bold"><b>with_custodian_and_ward</b></span>: Ties lifetimes
|
||||
of the arguments
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>with_custodian_and_ward_postcall</b></span>: Ties
|
||||
lifetimes of the arguments and results
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>return_internal_reference</b></span>: Ties lifetime
|
||||
of one argument to that of result
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>return_value_policy<T> with T one of:</b></span><div class="itemizedlist"><ul type="circle">
|
||||
<li>
|
||||
<span class="bold"><b>reference_existing_object</b></span>: naive (dangerous)
|
||||
approach
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>copy_const_reference</b></span>: Boost.Python
|
||||
v1 approach
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>copy_non_const_reference</b></span>:
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>manage_new_object</b></span>: Adopt a pointer
|
||||
and hold the instance
|
||||
</li>
|
||||
</ul></div>
|
||||
</li>
|
||||
</ul></div>
|
||||
<div class="sidebar">
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span> <span class="bold"><b>Remember the Zen, Luke:</b></span>
|
||||
</p>
|
||||
<p>
|
||||
"Explicit is better than implicit"
|
||||
</p>
|
||||
<p>
|
||||
"In the face of ambiguity, refuse the temptation to guess"
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.overloading"></a>Overloading</h3></div></div></div>
|
||||
<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>
|
||||
<pre class="programlisting"><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="special">{</span>
|
||||
<span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</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="special">{</span>
|
||||
<span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</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="special">{</span>
|
||||
<span class="keyword">return</span> <span class="keyword">true</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="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="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>
|
||||
<span class="special">};</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
Class X has 4 overloaded functions. We will start by introducing some member
|
||||
function pointer variables:
|
||||
</p>
|
||||
<pre class="programlisting"><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="special">=</span> <span class="special">&</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">)</span> <span class="special">=</span> <span class="special">&</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">)=</span> <span class="special">&</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">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
With these in hand, we can proceed to define and wrap this for Python:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx1</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx2</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx3</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx4</span><span class="special">)</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.default_arguments"></a>Default Arguments</h3></div></div></div>
|
||||
<p>
|
||||
Boost.Python wraps (member) function pointers. Unfortunately, C++ function
|
||||
pointers carry no default argument info. Take a function <tt class="literal">f</tt>
|
||||
with default arguments:
|
||||
</p>
|
||||
<pre class="programlisting"><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">"hello"</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
But the type of a pointer to the function <tt class="literal">f</tt> has no information
|
||||
about its default arguments:
|
||||
</p>
|
||||
<pre class="programlisting"><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></pre>
|
||||
<p>
|
||||
When we pass this function pointer to the <tt class="literal">def</tt> function,
|
||||
there is no way to retrieve the default arguments:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">f</span><span class="special">);</span> <span class="comment">// defaults lost!
|
||||
</span></pre>
|
||||
<p>
|
||||
Because of this, when wrapping C++ code, we had to resort to manual wrapping
|
||||
as outlined in the <a href="functions.html#python.overloading" title="Overloading">previous section</a>,
|
||||
or writing thin wrappers:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment">// write "thin wrappers"
|
||||
</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="comment">/*...*/</span>
|
||||
|
||||
<span class="comment">// in module init
|
||||
</span> <span class="identifier">def</span><span class="special">(</span><span class="string">"f"</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">"f"</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">"f"</span><span class="special">,</span> <span class="identifier">f1</span><span class="special">);</span> <span class="comment">// one argument
|
||||
</span></pre>
|
||||
<p>
|
||||
When you want to wrap functions (or member functions) that either:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
have default arguments, or
|
||||
</li>
|
||||
<li>
|
||||
are overloaded with a common sequence of initial arguments
|
||||
</li>
|
||||
</ul></div>
|
||||
<a name="default_arguments.boost_python_function_overloads"></a><h2>
|
||||
<a name="id467317"></a>
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS
|
||||
</h2>
|
||||
<p>
|
||||
Boost.Python now has a way to make it easier. For instance, given a function:
|
||||
</p>
|
||||
<pre class="programlisting"><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>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
The macro invocation:
|
||||
</p>
|
||||
<pre class="programlisting"><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>
|
||||
<p>
|
||||
will automatically create the thin wrappers for us. This macro will create
|
||||
a class <tt class="literal">foo_overloads</tt> that can be passed on to <tt class="literal">def(...)</tt>.
|
||||
The third and fourth macro argument are the minimum arguments and maximum
|
||||
arguments, respectively. In our <tt class="literal">foo</tt> function the minimum
|
||||
number of arguments is 1 and the maximum number of arguments is 4. The <tt class="literal">def(...)</tt>
|
||||
function will automatically add all the foo variants for us:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</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>
|
||||
<a name="default_arguments.boost_python_member_function_overloads"></a><h2>
|
||||
<a name="id467632"></a>
|
||||
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 class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</tt>, <tt class="literal">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>
|
||||
<pre class="programlisting"><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="char">'x'</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
The macro invocation:
|
||||
</p>
|
||||
<pre class="programlisting"><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>
|
||||
<p>
|
||||
will generate a set of thin wrappers for george's <tt class="literal">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 class="literal">george_overloads</tt> that can then be used
|
||||
as an argument to <tt class="literal">def(...)</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"wack_em"</span><span class="special">,</span> <span class="special">&</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>
|
||||
<p>
|
||||
See the <a href="../../../../v2/overloads.html#BOOST_PYTHON_FUNCTION_OVERLOADS-spec" target="_top">overloads
|
||||
reference</a> for details.
|
||||
</p>
|
||||
<a name="default_arguments.init_and_optional"></a><h2>
|
||||
<a name="id467992"></a>
|
||||
init and optional
|
||||
</h2>
|
||||
<p>
|
||||
A similar facility is provided for class constructors, again, with default
|
||||
arguments or a sequence of overloads. Remember <tt class="literal">init<...></tt>?
|
||||
For example, given a class X with a constructor:
|
||||
</p>
|
||||
<pre class="programlisting"><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="char">'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">"constructor"</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>
|
||||
<p>
|
||||
You can easily add this constructor to Boost.Python in one shot:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="identifier">init</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">optional</span><span class="special"><</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">></span> <span class="special">>())</span>
|
||||
</pre>
|
||||
<p>
|
||||
Notice the use of <tt class="literal">init<...></tt> and <tt class="literal">optional<...></tt>
|
||||
to signify the default (optional arguments).
|
||||
</p>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.auto_overloading"></a>Auto-Overloading</h3></div></div></div>
|
||||
<p>
|
||||
It was mentioned in passing in the previous section that <tt class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</tt>
|
||||
and <tt class="literal">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>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">/*...*/</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="special">{</span>
|
||||
<span class="comment">/*...*/</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="special">{</span>
|
||||
<span class="comment">/*...*/</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>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">/*...*/</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
Like in the previous section, we can generate thin wrappers for these overloaded
|
||||
functions in one-shot:
|
||||
</p>
|
||||
<pre class="programlisting"><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>
|
||||
<p>
|
||||
Then...
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">void</span><span class="special">(*)(</span><span class="keyword">bool</span><span class="special">,</span> <span class="keyword">int</span><span class="special">,</span> <span class="keyword">char</span><span class="special">))</span><span class="number">0</span><span class="special">,</span> <span class="identifier">foo_overloads</span><span class="special">());</span>
|
||||
</pre>
|
||||
<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="auto_overloading.manual_wrapping"></a><h2>
|
||||
<a name="id468767"></a>
|
||||
Manual Wrapping
|
||||
</h2>
|
||||
<p>
|
||||
It is important to emphasize however that <span class="bold"><b>the overloaded
|
||||
functions must have a common sequence of initial arguments</b></span>. Otherwise,
|
||||
our scheme above will not work. If this is not the case, we have to wrap
|
||||
our functions <a href="functions.html#python.overloading" title="Overloading">manually</a>.
|
||||
</p>
|
||||
<p>
|
||||
Actually, we can mix and match manual wrapping of overloaded functions and
|
||||
automatic wrapping through <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
|
||||
and its sister, <tt class="literal">BOOST_PYTHON_FUNCTION_OVERLOADS</tt>. Following
|
||||
up on our example presented in the section <a href="functions.html#python.overloading" title="Overloading">on
|
||||
overloading</a>, since the first 4 overload functins have a common sequence
|
||||
of initial arguments, we can use <tt class="literal">BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
|
||||
to automatically wrap the first three of the <tt class="literal">def</tt>s and
|
||||
manually wrap just the last. Here's how we'll do this:
|
||||
</p>
|
||||
<pre class="programlisting"><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>
|
||||
<p>
|
||||
Create a member function pointers as above for both X::f overloads:
|
||||
</p>
|
||||
<pre class="programlisting"><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">)</span> <span class="special">=</span> <span class="special">&</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">)</span> <span class="special">=</span> <span class="special">&</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">f</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Then...
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</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="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"f"</span><span class="special">,</span> <span class="identifier">fx2</span><span class="special">)</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
http://www.boost.org/LICENSE_1_0.txt </a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exposing.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="object.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
218
doc/tutorial/doc/html/python/hello.html
Normal file
@@ -0,0 +1,218 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title> Building Hello World</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
|
||||
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="prev" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="next" href="exposing.html" title=" Exposing Classes">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../index.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="exposing.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.hello"></a> Building Hello World</h2></div></div></div>
|
||||
<a name="hello.from_start_to_finish"></a><h2>
|
||||
<a name="id388718"></a>
|
||||
From Start To Finish
|
||||
</h2>
|
||||
<p>
|
||||
Now the first thing you'd want to do is to build the Hello World module and
|
||||
try it for yourself in Python. In this section, we will outline the steps necessary
|
||||
to achieve that. We will use the build tool that comes bundled with every boost
|
||||
distribution: <span class="bold"><b>bjam</b></span>.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top">
|
||||
<p>
|
||||
<span class="bold"><b>Building without bjam</b></span>
|
||||
</p>
|
||||
<p>
|
||||
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 <tt class="literal">bjam</tt>.
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
</td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
We will skip over the details. Our objective will be to simply create the hello
|
||||
world module and run it in Python. For a complete reference to building Boost.Python,
|
||||
check out: <a href="../../../../building.html" target="_top">building.html</a>. After
|
||||
this brief <span class="emphasis"><em>bjam</em></span> tutorial, we should have built the DLLs
|
||||
and run a python program using the extension.
|
||||
</p>
|
||||
<p>
|
||||
The tutorial example can be found in the directory: <tt class="literal">libs/python/example/tutorial</tt>.
|
||||
There, you can find:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
hello.cpp
|
||||
</li>
|
||||
<li>
|
||||
hello.py
|
||||
</li>
|
||||
<li>
|
||||
Jamroot
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
The <tt class="literal">hello.cpp</tt> file is our C++ hello world example. The
|
||||
<tt class="literal">Jamroot</tt> is a minimalist <span class="emphasis"><em>bjam</em></span> script
|
||||
that builds the DLLs for us. Finally, <tt class="literal">hello.py</tt> is our Python
|
||||
program that uses the extension in <tt class="literal">hello.cpp</tt>.
|
||||
</p>
|
||||
<p>
|
||||
Before anything else, you should have the bjam executable in your boost directory
|
||||
or somewhere in your path such that <tt class="literal">bjam</tt> can be executed
|
||||
in the command line. Pre-built Boost.Jam executables are available for most
|
||||
platforms. The complete list of Bjam executables can be found <a href="http://sourceforge.net/project/showfiles.php?group_id=7586" target="_top">here</a>.
|
||||
</p>
|
||||
<a name="hello.let_s_jam_"></a><h2>
|
||||
<a name="id387300"></a>
|
||||
Let's Jam!
|
||||
</h2>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/jam.png" alt="jam"></span>
|
||||
</p>
|
||||
<p>
|
||||
<a href="../../../../../example/tutorial/Jamroot" target="_top">Here</a> is our minimalist
|
||||
Jamroot file. Simply copy the file and tweak <tt class="literal">use-project boost</tt>
|
||||
to where your boost root directory is and your OK.
|
||||
</p>
|
||||
<p>
|
||||
The comments contained in the Jamrules file above should be sufficient to get
|
||||
you going.
|
||||
</p>
|
||||
<a name="hello.running_bjam"></a><h2>
|
||||
<a name="id387357"></a>
|
||||
Running bjam
|
||||
</h2>
|
||||
<p>
|
||||
<span class="emphasis"><em>bjam</em></span> is run using your operating system's command line
|
||||
interpreter.
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote">
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
Start it up.
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
</blockquote></div>
|
||||
<p>
|
||||
A file called user-config.jam in your home directory is used to configure your
|
||||
tools. In Windows, your home directory can be found by typing:
|
||||
</p>
|
||||
<pre class="programlisting">ECHO %HOMEDRIVE%%HOMEPATH%
|
||||
</pre>
|
||||
<p>
|
||||
into a command prompt window. Your file should at least have the rules for
|
||||
your compiler and your python installation. A specific example of this on Windows
|
||||
would be:
|
||||
</p>
|
||||
<pre class="programlisting"># MSVC configuration
|
||||
using msvc : 8.0 ;
|
||||
|
||||
# Python configuration
|
||||
using python : 2.4 : C:/dev/tools<span class="emphasis"><em>Python</em></span> ;
|
||||
</pre>
|
||||
<p>
|
||||
The first rule tells Bjam to use the MSVC 8.0 compiler and associated tools.
|
||||
The second rule provides information on Python, its version and where it is
|
||||
located. The above assumes that the Python installation is in <tt class="literal">C:/dev/tools/Python/</tt>.
|
||||
If you have one fairly "standard" python installation for your platform,
|
||||
you might not need to do this.
|
||||
</p>
|
||||
<p>
|
||||
Now we are ready... Be sure to <tt class="literal">cd</tt> to <tt class="literal">libs/python/example/tutorial</tt>
|
||||
where the tutorial <tt class="literal">"hello.cpp"</tt> and the <tt class="literal">"Jamroot"</tt>
|
||||
is situated.
|
||||
</p>
|
||||
<p>
|
||||
Finally:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">bjam</span>
|
||||
</pre>
|
||||
<p>
|
||||
It should be building now:
|
||||
</p>
|
||||
<pre class="programlisting">cd C:\dev\boost\libs\python\example\tutorial
|
||||
bjam
|
||||
...patience...
|
||||
...found 1101 targets...
|
||||
...updating 35 targets...
|
||||
</pre>
|
||||
<p>
|
||||
And so on... Finally:
|
||||
</p>
|
||||
<pre class="programlisting">Creating library <span class="emphasis"><em>path-to-boost_python.dll</em></span>
|
||||
Creating library <span class="emphasis"><em>path-to-'''hello_ext'''.exp</em></span>
|
||||
**passed** ... hello.test
|
||||
...updated 35 targets...
|
||||
</pre>
|
||||
<p>
|
||||
Or something similar. If all is well, you should now have built the DLLs and
|
||||
run the Python program.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top"><p>
|
||||
Starting from Boost 1.35, bjam erases the generated executables (e.g. pyd
|
||||
file) after the test has concluded to conserve disk space. To keep bjam from
|
||||
doing that, pass --preserve-test-targets to bjam.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<div class="blockquote"><blockquote class="blockquote">
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
<span class="bold"><b>There you go... Have fun!</b></span>
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
</blockquote></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
http://www.boost.org/LICENSE_1_0.txt </a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../index.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="exposing.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
199
doc/tutorial/doc/html/python/iterators.html
Normal file
@@ -0,0 +1,199 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Iterators</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
|
||||
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="prev" href="embedding.html" title="Embedding">
|
||||
<link rel="next" href="exception.html" title=" Exception Translation">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="embedding.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="exception.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.iterators"></a>Iterators</h2></div></div></div>
|
||||
<p>
|
||||
In C++, and STL in particular, we see iterators everywhere. Python also has
|
||||
iterators, but these are two very different beasts.
|
||||
</p>
|
||||
<p>
|
||||
<span class="bold"><b>C++ iterators:</b></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
C++ has 5 type categories (random-access, bidirectional, forward, input,
|
||||
output)
|
||||
</li>
|
||||
<li>
|
||||
There are 2 Operation categories: reposition, access
|
||||
</li>
|
||||
<li>
|
||||
A pair of iterators is needed to represent a (first/last) range.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
<span class="bold"><b>Python Iterators:</b></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
1 category (forward)
|
||||
</li>
|
||||
<li>
|
||||
1 operation category (next())
|
||||
</li>
|
||||
<li>
|
||||
Raises StopIteration exception at end
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
The typical Python iteration protocol: <tt class="literal"><span class="bold"><b>for y
|
||||
in x...</b></span></tt> is as follows:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><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="comment"># get 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="comment"># get each item
|
||||
</span> <span class="special">...</span> <span class="comment"># process y
|
||||
</span><span class="keyword">except</span> <span class="identifier">StopIteration</span><span class="special">:</span> <span class="keyword">pass</span> <span class="comment"># iterator exhausted
|
||||
</span></pre>
|
||||
<p>
|
||||
Boost.Python provides some mechanisms to make C++ iterators play along nicely
|
||||
as Python iterators. What we need to do is to produce appropriate <tt class="computeroutput"><span class="identifier">__iter__</span></tt> function from C++ iterators that
|
||||
is compatible with the Python iteration protocol. For example:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">get_iterator</span> <span class="special">=</span> <span class="identifier">iterator</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>();</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>
|
||||
<p>
|
||||
Or for use in class_<>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"__iter__"</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special"><</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>())</span>
|
||||
</pre>
|
||||
<p>
|
||||
<span class="bold"><b>range</b></span>
|
||||
</p>
|
||||
<p>
|
||||
We can create a Python savvy iterator using the range function:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
range(start, finish)
|
||||
</li>
|
||||
<li>
|
||||
range<Policies,Target>(start, finish)
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Here, start/finish may be one of:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
member data pointers
|
||||
</li>
|
||||
<li>
|
||||
member function pointers
|
||||
</li>
|
||||
<li>
|
||||
adaptable function object (use Target parameter)
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
<span class="bold"><b>iterator</b></span>
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc"><li>
|
||||
iterator<T, Policies>()
|
||||
</li></ul></div>
|
||||
<p>
|
||||
Given a container <tt class="literal">T</tt>, iterator is a shortcut that simply
|
||||
calls <tt class="literal">range</tt> with &T::begin, &T::end.
|
||||
</p>
|
||||
<p>
|
||||
Let's put this into action... Here's an example from some hypothetical bogon
|
||||
Particle accelerator code:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">f</span> <span class="special">=</span> <span class="identifier">Field</span><span class="special">()</span>
|
||||
<span class="keyword">for</span> <span class="identifier">x</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">pions</span><span class="special">:</span>
|
||||
<span class="identifier">smash</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span>
|
||||
<span class="keyword">for</span> <span class="identifier">y</span> <span class="keyword">in</span> <span class="identifier">f</span><span class="special">.</span><span class="identifier">bogons</span><span class="special">:</span>
|
||||
<span class="identifier">count</span><span class="special">(</span><span class="identifier">y</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
Now, our C++ Wrapper:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">class_</span><span class="special"><</span><span class="identifier">F</span><span class="special">>(</span><span class="string">"Field"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">property</span><span class="special">(</span><span class="string">"pions"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">p_begin</span><span class="special">,</span> <span class="special">&</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">"bogons"</span><span class="special">,</span> <span class="identifier">range</span><span class="special">(&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_begin</span><span class="special">,</span> <span class="special">&</span><span class="identifier">F</span><span class="special">::</span><span class="identifier">b_end</span><span class="special">));</span>
|
||||
</pre>
|
||||
<p>
|
||||
<span class="bold"><b>stl_input_iterator</b></span>
|
||||
</p>
|
||||
<p>
|
||||
So far, we have seen how to expose C++ iterators and ranges to Python. Sometimes
|
||||
we wish to go the other way, though: we'd like to pass a Python sequence to
|
||||
an STL algorithm or use it to initialize an STL container. We need to make
|
||||
a Python iterator look like an STL iterator. For that, we use <tt class="computeroutput"><span class="identifier">stl_input_iterator</span><span class="special"><></span></tt>.
|
||||
Consider how we might implement a function that exposes <tt class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">assign</span><span class="special">()</span></tt> to Python:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">void</span> <span class="identifier">list_assign</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">l</span><span class="special">,</span> <span class="identifier">object</span> <span class="identifier">o</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="comment">// Turn a Python sequence into an STL input range
|
||||
</span> <span class="identifier">stl_input_iterator</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">begin</span><span class="special">(</span><span class="identifier">o</span><span class="special">),</span> <span class="identifier">end</span><span class="special">;</span>
|
||||
<span class="identifier">l</span><span class="special">.</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">begin</span><span class="special">,</span> <span class="identifier">end</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="comment">// Part of the wrapper for list<int>
|
||||
</span><span class="identifier">class_</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="special">>(</span><span class="string">"list_int"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">def</span><span class="special">(</span><span class="string">"assign"</span><span class="special">,</span> <span class="special">&</span><span class="identifier">list_assign</span><span class="special"><</span><span class="keyword">int</span><span class="special">>)</span>
|
||||
<span class="comment">// ...
|
||||
</span> <span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Now in Python, we can assign any integer sequence to <tt class="computeroutput"><span class="identifier">list_int</span></tt>
|
||||
objects:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">x</span> <span class="special">=</span> <span class="identifier">list_int</span><span class="special">();</span>
|
||||
<span class="identifier">x</span><span class="special">.</span><span class="identifier">assign</span><span class="special">([</span><span class="number">1</span><span class="special">,</span><span class="number">2</span><span class="special">,</span><span class="number">3</span><span class="special">,</span><span class="number">4</span><span class="special">,</span><span class="number">5</span><span class="special">])</span>
|
||||
</pre>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
http://www.boost.org/LICENSE_1_0.txt </a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="embedding.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="exception.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
338
doc/tutorial/doc/html/python/object.html
Normal file
@@ -0,0 +1,338 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title> Object Interface</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
|
||||
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="prev" href="functions.html" title="Functions">
|
||||
<link rel="next" href="embedding.html" title="Embedding">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="functions.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="embedding.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.object"></a> Object Interface</h2></div></div></div>
|
||||
<div class="toc"><dl>
|
||||
<dt><span class="section"><a href="object.html#python.basic_interface">Basic Interface</a></span></dt>
|
||||
<dt><span class="section"><a href="object.html#python.derived_object_types">Derived Object types</a></span></dt>
|
||||
<dt><span class="section"><a href="object.html#python.extracting_c___objects">Extracting C++ objects</a></span></dt>
|
||||
<dt><span class="section"><a href="object.html#python.enums">Enums</a></span></dt>
|
||||
</dl></div>
|
||||
<p>
|
||||
Python is dynamically typed, unlike C++ which is statically typed. Python variables
|
||||
may hold an integer, a float, list, dict, tuple, str, long etc., among other
|
||||
things. In the viewpoint of Boost.Python and C++, these Pythonic variables
|
||||
are just instances of class <tt class="literal">object</tt>. We will see in this
|
||||
chapter how to deal with Python objects.
|
||||
</p>
|
||||
<p>
|
||||
As mentioned, one of the goals of Boost.Python is to provide a bidirectional
|
||||
mapping between C++ and Python while maintaining the Python feel. Boost.Python
|
||||
C++ <tt class="literal">object</tt>s are as close as possible to Python. This should
|
||||
minimize the learning curve significantly.
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/python.png" alt="python"></span>
|
||||
</p>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.basic_interface"></a>Basic Interface</h3></div></div></div>
|
||||
<p>
|
||||
Class <tt class="literal">object</tt> wraps <tt class="literal">PyObject*</tt>. All the
|
||||
intricacies of dealing with <tt class="literal">PyObject</tt>s such as managing
|
||||
reference counting are handled by the <tt class="literal">object</tt> class. C++
|
||||
object interoperability is seamless. Boost.Python C++ <tt class="literal">object</tt>s
|
||||
can in fact be explicitly constructed from any C++ object.
|
||||
</p>
|
||||
<p>
|
||||
To illustrate, this Python code snippet:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">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="string">'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="string">'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</span>
|
||||
|
||||
<span class="keyword">def</span> <span class="identifier">getfunc</span><span class="special">():</span>
|
||||
<span class="keyword">return</span> <span class="identifier">f</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Can be rewritten in C++ using Boost.Python facilities this way:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><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>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">y</span> <span class="special">==</span> <span class="string">"foo"</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">"bar"</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">"items"</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="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="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>
|
||||
<p>
|
||||
Apart from cosmetic differences due to the fact that we are writing the code
|
||||
in C++, the look and feel should be immediately apparent to the Python coder.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.derived_object_types"></a>Derived Object types</h3></div></div></div>
|
||||
<p>
|
||||
Boost.Python comes with a set of derived <tt class="literal">object</tt> types
|
||||
corresponding to that of Python's:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
list
|
||||
</li>
|
||||
<li>
|
||||
dict
|
||||
</li>
|
||||
<li>
|
||||
tuple
|
||||
</li>
|
||||
<li>
|
||||
str
|
||||
</li>
|
||||
<li>
|
||||
long_
|
||||
</li>
|
||||
<li>
|
||||
enum
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
These derived <tt class="literal">object</tt> types act like real Python types.
|
||||
For instance:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">str</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==></span> <span class="string">"1"</span>
|
||||
</pre>
|
||||
<p>
|
||||
Wherever appropriate, a particular derived <tt class="literal">object</tt> has
|
||||
corresponding Python type's methods. For instance, <tt class="literal">dict</tt>
|
||||
has a <tt class="literal">keys()</tt> method:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">d</span><span class="special">.</span><span class="identifier">keys</span><span class="special">()</span>
|
||||
</pre>
|
||||
<p>
|
||||
<tt class="literal">make_tuple</tt> is provided for declaring <span class="emphasis"><em>tuple literals</em></span>.
|
||||
Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">make_tuple</span><span class="special">(</span><span class="number">123</span><span class="special">,</span> <span class="char">'D'</span><span class="special">,</span> <span class="string">"Hello, World"</span><span class="special">,</span> <span class="number">0.0</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
In C++, when Boost.Python <tt class="literal">object</tt>s are used as arguments
|
||||
to functions, subtype matching is required. For example, when a function
|
||||
<tt class="literal">f</tt>, as declared below, is wrapped, it will only accept
|
||||
instances of Python's <tt class="literal">str</tt> type and subtypes.
|
||||
</p>
|
||||
<pre class="programlisting"><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">"upper"</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">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</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>
|
||||
<p>
|
||||
In finer detail:
|
||||
</p>
|
||||
<pre class="programlisting"><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>
|
||||
</pre>
|
||||
<p>
|
||||
Illustrates that we provide versions of the str type's methods as C++ member
|
||||
functions.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"%s is bigger than %s"</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>
|
||||
</pre>
|
||||
<p>
|
||||
Demonstrates that you can write the C++ equivalent of <tt class="literal">"format"
|
||||
% x,y,z</tt> in Python, which is useful since there's no easy way to
|
||||
do that in std C++.
|
||||
</p>
|
||||
<div class="sidebar"><p>
|
||||
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>Beware</b></span> the common pitfall
|
||||
of forgetting that the constructors of most of Python's mutable types make
|
||||
copies, just as in Python.
|
||||
</p></div>
|
||||
<p>
|
||||
Python:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></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="comment"># copies x.__dict__
|
||||
</span><span class="special">>>></span> <span class="identifier">d</span><span class="special">[</span><span class="string">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span> <span class="comment"># modifies the copy
|
||||
</span></pre>
|
||||
<p>
|
||||
C++:
|
||||
</p>
|
||||
<pre class="programlisting"><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">"__dict__"</span><span class="special">));</span> <span class="comment">// copies x.__dict__
|
||||
</span><span class="identifier">d</span><span class="special">[</span><span class="char">'whatever'</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies the copy
|
||||
</span></pre>
|
||||
<a name="derived_object_types.class__lt_t_gt__as_objects"></a><h2>
|
||||
<a name="id470756"></a>
|
||||
class_<T> as objects
|
||||
</h2>
|
||||
<p>
|
||||
Due to the dynamic nature of Boost.Python objects, any <tt class="literal">class_<T></tt>
|
||||
may also be one of these types! The following code snippet wraps the class
|
||||
(type) object.
|
||||
</p>
|
||||
<p>
|
||||
We can use this to create wrapped instances. Example:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">object</span> <span class="identifier">vec345</span> <span class="special">=</span> <span class="special">(</span>
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">Vec2</span><span class="special">>(</span><span class="string">"Vec2"</span><span class="special">,</span> <span class="identifier">init</span><span class="special"><</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">>())</span>
|
||||
<span class="special">.</span><span class="identifier">def_readonly</span><span class="special">(</span><span class="string">"length"</span><span class="special">,</span> <span class="special">&</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">"angle"</span><span class="special">,</span> <span class="special">&</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">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">"length"</span><span class="special">)</span> <span class="special">==</span> <span class="number">5.0</span><span class="special">);</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.extracting_c___objects"></a>Extracting C++ objects</h3></div></div></div>
|
||||
<p>
|
||||
At some point, we will need to get C++ values out of object instances. This
|
||||
can be achieved with the <tt class="literal">extract<T></tt> function. Consider
|
||||
the following:
|
||||
</p>
|
||||
<pre class="programlisting"><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">"length"</span><span class="special">);</span> <span class="comment">// compile error
|
||||
</span></pre>
|
||||
<p>
|
||||
In the code above, we got a compiler error because Boost.Python <tt class="literal">object</tt>
|
||||
can't be implicitly converted to <tt class="literal">double</tt>s. Instead, what
|
||||
we wanted to do above can be achieved by writing:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="keyword">double</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">"length"</span><span class="special">));</span>
|
||||
<span class="identifier">Vec2</span><span class="special">&</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">extract</span><span class="special"><</span><span class="identifier">Vec2</span><span class="special">&>(</span><span class="identifier">o</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">l</span> <span class="special">==</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">length</span><span class="special">());</span>
|
||||
</pre>
|
||||
<p>
|
||||
The first line attempts to extract the "length" attribute of the
|
||||
Boost.Python <tt class="literal">object</tt>. The second line attempts to <span class="emphasis"><em>extract</em></span>
|
||||
the <tt class="literal">Vec2</tt> object from held by the Boost.Python <tt class="literal">object</tt>.
|
||||
</p>
|
||||
<p>
|
||||
Take note that we said "attempt to" above. What if the Boost.Python
|
||||
<tt class="literal">object</tt> does not really hold a <tt class="literal">Vec2</tt>
|
||||
type? This is certainly a possibility considering the dynamic nature of Python
|
||||
<tt class="literal">object</tt>s. To be on the safe side, if the C++ type can't
|
||||
be extracted, an appropriate exception is thrown. To avoid an exception,
|
||||
we need to test for extractibility:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">extract</span><span class="special"><</span><span class="identifier">Vec2</span><span class="special">&></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">&</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">x</span><span class="special">();</span> <span class="special">...</span>
|
||||
</pre>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> The astute reader might have noticed that the <tt class="literal">extract<T></tt>
|
||||
facility in fact solves the mutable copying problem:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">dict</span> <span class="identifier">d</span> <span class="special">=</span> <span class="identifier">extract</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">attr</span><span class="special">(</span><span class="string">"__dict__"</span><span class="special">));</span>
|
||||
<span class="identifier">d</span><span class="special">[</span><span class="string">"whatever"</span><span class="special">]</span> <span class="special">=</span> <span class="number">3</span><span class="special">;</span> <span class="comment">// modifies x.__dict__ !
|
||||
</span></pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.enums"></a>Enums</h3></div></div></div>
|
||||
<p>
|
||||
Boost.Python has a nifty facility to capture and wrap C++ enums. While Python
|
||||
has no <tt class="literal">enum</tt> type, we'll often want to expose our C++ enums
|
||||
to Python as an <tt class="literal">int</tt>. Boost.Python's enum facility makes
|
||||
this easy while taking care of the proper conversions from Python's dynamic
|
||||
typing to C++'s strong static typing (in C++, ints cannot be implicitly converted
|
||||
to enums). To illustrate, given a C++ enum:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">enum</span> <span class="identifier">choice</span> <span class="special">{</span> <span class="identifier">red</span><span class="special">,</span> <span class="identifier">blue</span> <span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
the construct:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">enum_</span><span class="special"><</span><span class="identifier">choice</span><span class="special">>(</span><span class="string">"choice"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"red"</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">"blue"</span><span class="special">,</span> <span class="identifier">blue</span><span class="special">)</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
can be used to expose to Python. The new enum type is created in the current
|
||||
<tt class="literal">scope()</tt>, which is usually the current module. The snippet
|
||||
above creates a Python class derived from Python's <tt class="literal">int</tt>
|
||||
type which is associated with the C++ type passed as its first parameter.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top">
|
||||
<p>
|
||||
<span class="bold"><b>what is a scope?</b></span>
|
||||
</p>
|
||||
<p>
|
||||
The scope is a class that has an associated global Python object which
|
||||
controls the Python namespace in which new extension classes and wrapped
|
||||
functions will be defined as attributes. Details can be found <a href="../../../../v2/scope.html" target="_top">here</a>.
|
||||
</p>
|
||||
</td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
You can access those values in Python as
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
|
||||
<span class="identifier">my_module</span><span class="special">.</span><span class="identifier">choice</span><span class="special">.</span><span class="identifier">red</span>
|
||||
</pre>
|
||||
<p>
|
||||
where my_module is the module where the enum is declared. You can also create
|
||||
a new scope around a class:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">scope</span> <span class="identifier">in_X</span> <span class="special">=</span> <span class="identifier">class_</span><span class="special"><</span><span class="identifier">X</span><span class="special">>(</span><span class="string">"X"</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>
|
||||
|
||||
<span class="comment">// Expose X::nested as X.nested
|
||||
</span><span class="identifier">enum_</span><span class="special"><</span><span class="identifier">X</span><span class="special">::</span><span class="identifier">nested</span><span class="special">>(</span><span class="string">"nested"</span><span class="special">)</span>
|
||||
<span class="special">.</span><span class="identifier">value</span><span class="special">(</span><span class="string">"red"</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">"blue"</span><span class="special">,</span> <span class="identifier">blue</span><span class="special">)</span>
|
||||
<span class="special">;</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
http://www.boost.org/LICENSE_1_0.txt </a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="functions.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="embedding.html"><img src="../../../../../../../doc/html/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
452
doc/tutorial/doc/html/python/techniques.html
Normal file
@@ -0,0 +1,452 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title> General Techniques</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/html/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.66.1">
|
||||
<link rel="start" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. python 1.0">
|
||||
<link rel="prev" href="exception.html" title=" Exception Translation">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exception.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="python.techniques"></a> General Techniques</h2></div></div></div>
|
||||
<div class="toc"><dl>
|
||||
<dt><span class="section"><a href="techniques.html#python.creating_packages">Creating Packages</a></span></dt>
|
||||
<dt><span class="section"><a href="techniques.html#python.extending_wrapped_objects_in_python">Extending Wrapped Objects in Python</a></span></dt>
|
||||
<dt><span class="section"><a href="techniques.html#python.reducing_compiling_time">Reducing Compiling Time</a></span></dt>
|
||||
</dl></div>
|
||||
<p>
|
||||
Here are presented some useful techniques that you can use while wrapping code
|
||||
with Boost.Python.
|
||||
</p>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.creating_packages"></a>Creating Packages</h3></div></div></div>
|
||||
<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" target="_top">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 class="literal">sounds</tt>. Our library already has a neat C++ namespace hierarchy,
|
||||
like so:
|
||||
</p>
|
||||
<pre class="programlisting"><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>
|
||||
<p>
|
||||
We would like to present this same hierarchy to the Python user, allowing
|
||||
him to write code like this:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">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="comment"># echo is a C++ function
|
||||
</span></pre>
|
||||
<p>
|
||||
The first step is to write the wrapping code. We have to export each module
|
||||
separately with Boost.Python, like this:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">/*</span> <span class="identifier">file</span> <span class="identifier">core</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">core</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="special">/*</span> <span class="identifier">export</span> <span class="identifier">everything</span> <span class="keyword">in</span> <span class="identifier">the</span> <span class="identifier">sounds</span><span class="special">::</span><span class="identifier">core</span> <span class="identifier">namespace</span> <span class="special">*/</span>
|
||||
<span class="special">...</span>
|
||||
<span class="special">}</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="special">{</span>
|
||||
<span class="special">/*</span> <span class="identifier">export</span> <span class="identifier">everything</span> <span class="keyword">in</span> <span class="identifier">the</span> <span class="identifier">sounds</span><span class="special">::</span><span class="identifier">io</span> <span class="identifier">namespace</span> <span class="special">*/</span>
|
||||
<span class="special">...</span>
|
||||
<span class="special">}</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="special">{</span>
|
||||
<span class="special">/*</span> <span class="identifier">export</span> <span class="identifier">everything</span> <span class="keyword">in</span> <span class="identifier">the</span> <span class="identifier">sounds</span><span class="special">::</span><span class="identifier">filters</span> <span class="identifier">namespace</span> <span class="special">*/</span>
|
||||
<span class="special">...</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
Compiling these files will generate the following Python extensions: <tt class="literal">core.pyd</tt>,
|
||||
<tt class="literal">io.pyd</tt> and <tt class="literal">filters.pyd</tt>.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top"><p>
|
||||
The extension <tt class="literal">.pyd</tt> is used for python extension modules,
|
||||
which are just shared libraries. Using the default for your system, like
|
||||
<tt class="literal">.so</tt> for Unix and <tt class="literal">.dll</tt> for Windows,
|
||||
works just as well.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
Now, we create this directory structure for our Python package:
|
||||
</p>
|
||||
<pre class="programlisting">sounds/
|
||||
__init__.py
|
||||
core.pyd
|
||||
filters.pyd
|
||||
io.pyd
|
||||
</pre>
|
||||
<p>
|
||||
The file <tt class="literal">__init__.py</tt> is what tells Python that the directory
|
||||
<tt class="literal">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 class="literal">sounds</tt>
|
||||
into his <a href="http://www.python.org/doc/current/tut/node8.html#SECTION008110000000000000000" target="_top">PYTHONPATH</a>
|
||||
and fire up the interpreter:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">io</span>
|
||||
<span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</span>
|
||||
<span class="special">>>></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="string">'file.mp3'</span><span class="special">)</span>
|
||||
<span class="special">>>></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>
|
||||
<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 <span class="emphasis"><em>pure</em></span> 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>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><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="special">{</span>
|
||||
<span class="special">...</span>
|
||||
<span class="comment">/* export everything in the sounds::core namespace */</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
Note that we added an underscore to the module name. The filename will have
|
||||
to be changed to <tt class="literal">_core.pyd</tt> as well, and we do the same
|
||||
to the other extension modules. Now, we change our package hierarchy like
|
||||
so:
|
||||
</p>
|
||||
<pre class="programlisting">sounds/
|
||||
__init__.py
|
||||
core/
|
||||
__init__.py
|
||||
<span class="underline">core.pyd
|
||||
filters/
|
||||
\</span>_init__.py
|
||||
<span class="underline">filters.pyd
|
||||
io/
|
||||
\</span>_init__.py
|
||||
_io.pyd
|
||||
</pre>
|
||||
<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>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">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">>>></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>
|
||||
<p>
|
||||
which is not what we want. But here enters the <tt class="literal">__init__.py</tt>
|
||||
magic: everything that is brought to the <tt class="literal">__init__.py</tt> namespace
|
||||
can be accessed directly by the user. So, all we have to do is bring the
|
||||
entire namespace from <tt class="literal">_core.pyd</tt> to <tt class="literal">core/__init__.py</tt>.
|
||||
So add this line of code to <tt class="literal">sounds<span class="emphasis"><em>core</em></span>__init__.py</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">_core</span> <span class="keyword">import</span> <span class="special">*</span>
|
||||
</pre>
|
||||
<p>
|
||||
We do the same for the other packages. Now the user accesses the functions
|
||||
and classes in the extension modules like before:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</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>
|
||||
</pre>
|
||||
<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 <span class="emphasis"><em>pure</em></span>
|
||||
Python function, <tt class="literal">echo_noise</tt>, to the <tt class="literal">filters</tt>
|
||||
package. This function applies both the <tt class="literal">echo</tt> and <tt class="literal">noise</tt>
|
||||
filters in sequence in the given <tt class="literal">sound</tt> object. We create
|
||||
a file named <tt class="literal">sounds/filters/echo_noise.py</tt> and code our
|
||||
function:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">import</span> <span class="identifier">_filters</span>
|
||||
<span class="keyword">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>
|
||||
<p>
|
||||
Next, we add this line to <tt class="literal">sounds<span class="emphasis"><em>filters</em></span>__init__.py</tt>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">echo_noise</span> <span class="keyword">import</span> <span class="identifier">echo_noise</span>
|
||||
</pre>
|
||||
<p>
|
||||
And that's it. The user now accesses this function like any other function
|
||||
from the <tt class="literal">filters</tt> package:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">import</span> <span class="identifier">sounds</span><span class="special">.</span><span class="identifier">filters</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_noise</span><span class="special">(...)</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.extending_wrapped_objects_in_python"></a>Extending Wrapped Objects in Python</h3></div></div></div>
|
||||
<p>
|
||||
Thanks to Python's flexibility, you can easily add new methods to a class,
|
||||
even after it was already created:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></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="keyword">pass</span>
|
||||
<span class="special">>>></span>
|
||||
<span class="special">>>></span> <span class="comment"># a regular function
|
||||
</span><span class="special">>>></span> <span class="keyword">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="string">'A C instance!'</span>
|
||||
<span class="special">>>></span>
|
||||
<span class="special">>>></span> <span class="comment"># now we turn it in a member function
|
||||
</span><span class="special">>>></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">>>></span>
|
||||
<span class="special">>>></span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">C</span><span class="special">()</span>
|
||||
<span class="special">>>></span> <span class="keyword">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">!</span>
|
||||
<span class="special">>>></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>
|
||||
<p>
|
||||
Yes, Python rox. <span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span>
|
||||
</p>
|
||||
<p>
|
||||
We can do the same with classes that were wrapped with Boost.Python. Suppose
|
||||
we have a class <tt class="literal">point</tt> in C++:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><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="special">{</span>
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">point</span><span class="special">>(</span><span class="string">"point"</span><span class="special">)...;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
If we are using the technique from the previous session, <a href="techniques.html#python.creating_packages" title="Creating Packages">Creating
|
||||
Packages</a>, we can code directly into <tt class="literal">geom/__init__.py</tt>:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">from</span> <span class="identifier">_geom</span> <span class="keyword">import</span> <span class="special">*</span>
|
||||
|
||||
<span class="comment"># a regular function
|
||||
</span><span class="keyword">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="comment"># now we turn it into a member 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>
|
||||
<p>
|
||||
<span class="bold"><b>All</b></span> point instances created from C++ will
|
||||
also have this member function! This technique has several advantages:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<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></div>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment"># The one Boost.Python uses for all wrapped classes.
|
||||
</span><span class="comment"># You can use here any class exported by Boost instead of "point"
|
||||
</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="keyword">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="keyword">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="keyword">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="keyword">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="comment"># inject some methods in the point 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="keyword">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="string">'Point(x=%s, y=%s)'</span> <span class="special">%</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="keyword">def</span> <span class="identifier">foo</span><span class="special">(</span><span class="identifier">self</span><span class="special">):</span>
|
||||
<span class="keyword">print</span> <span class="string">'foo!'</span>
|
||||
</pre>
|
||||
<p>
|
||||
Now let's see how it got:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="special">>>></span> <span class="keyword">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">)</span>
|
||||
<span class="special">>>></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>
|
||||
<p>
|
||||
Another useful idea is to replace constructors with factory functions:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">_point</span> <span class="special">=</span> <span class="identifier">point</span>
|
||||
|
||||
<span class="keyword">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>
|
||||
<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>
|
||||
</div>
|
||||
<div class="section" lang="en">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="python.reducing_compiling_time"></a>Reducing Compiling Time</h3></div></div></div>
|
||||
<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>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment">/* file point.cpp */</span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||||
|
||||
<span class="keyword">void</span> <span class="identifier">export_point</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">point</span><span class="special">>(</span><span class="string">"point"</span><span class="special">)...;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="comment">/* file triangle.cpp */</span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">triangle</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||||
|
||||
<span class="keyword">void</span> <span class="identifier">export_triangle</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">triangle</span><span class="special">>(</span><span class="string">"triangle"</span><span class="special">)...;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
Now you create a file <tt class="literal">main.cpp</tt>, which contains the <tt class="literal">BOOST_PYTHON_MODULE</tt>
|
||||
macro, and call the various export functions inside it.
|
||||
</p>
|
||||
<pre class="programlisting"><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="special">{</span>
|
||||
<span class="identifier">export_point</span><span class="special">();</span>
|
||||
<span class="identifier">export_triangle</span><span class="special">();</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
Compiling and linking together all this files produces the same result as
|
||||
the usual approach:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</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">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">point</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">triangle</span><span class="special">.</span><span class="identifier">h</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="special">{</span>
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">point</span><span class="special">>(</span><span class="string">"point"</span><span class="special">)...;</span>
|
||||
<span class="identifier">class_</span><span class="special"><</span><span class="identifier">triangle</span><span class="special">>(</span><span class="string">"triangle"</span><span class="special">)...;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<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>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top"><p>
|
||||
If you're exporting your classes with <a href="../../../../../pyste/index.html" target="_top">Pyste</a>,
|
||||
take a look at the <tt class="literal">--multiple</tt> option, that generates
|
||||
the wrappers in various files as demonstrated here.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/html/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td colspan="2" align="left" valign="top"><p>
|
||||
This method is useful too if you are getting the error message <span class="emphasis"><em>"fatal
|
||||
error C1204:Compiler limit:internal structure overflow"</em></span>
|
||||
when compiling a large source file, as explained in the <a href="../../../../v2/faq.html#c1204" target="_top">FAQ</a>.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
|
||||
http://www.boost.org/LICENSE_1_0.txt </a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exception.html"><img src="../../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../../../doc/html/images/home.png" alt="Home"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
1968
doc/tutorial/doc/tutorial.qbk
Normal file
18
doc/tutorial/index.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
|
||||
</head>
|
||||
<body>
|
||||
Automatic redirection failed, click this
|
||||
<a href="doc/html/index.html">link</a> <hr>
|
||||
<p>© Copyright Beman Dawes, 2001</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. (See
|
||||
accompanying file <a href="../../../../LICENSE_1_0.txt">
|
||||
LICENSE_1_0.txt</a> or copy at
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,62 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<title>
|
||||
A Peek Under the Hood
|
||||
</title>
|
||||
<h1>
|
||||
<img src="../../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center"
|
||||
width="277" height="86">
|
||||
</h1>
|
||||
<h1>
|
||||
A Peek Under the Hood
|
||||
</h1>
|
||||
<p>
|
||||
Declaring a <code>class_builder<T></code> causes the instantiation
|
||||
of an <code>extension_class<T></code> to which it forwards all
|
||||
member function calls and which is doing most of the real work.
|
||||
<code>extension_class<T></code> is a subclass of <code>
|
||||
PyTypeObject</code>, the <code> struct</code> which Python's 'C' API uses
|
||||
to describe a type. <a href="example1.html#world_class">An instance of the
|
||||
<code>extension_class<></code></a> becomes the Python type object
|
||||
corresponding to <code>hello::world</code>. When we <a href=
|
||||
"example1.html#add_world_class">add it to the module</a> it goes into the
|
||||
module's dictionary to be looked up under the name "world".
|
||||
<p>
|
||||
Boost.Python uses C++'s template argument deduction mechanism to determine the
|
||||
types of arguments to functions (except constructors, for which we must
|
||||
<a href="example1.html#Constructor_example">provide an argument list</a>
|
||||
because they can't be named in C++). Then, it calls the appropriate
|
||||
overloaded functions <code>PyObject*
|
||||
to_python(</code><em>S</em><code>)</code> and <em>
|
||||
S'</em><code>from_python(PyObject*,
|
||||
type<</code><em>S</em><code>>)</code> which convert between any C++
|
||||
type <em>S</em> and a <code>PyObject*</code>, the type which represents a
|
||||
reference to any Python object in its 'C' API. The <a href=
|
||||
"example1.html#world_class"><code>extension_class<T></code></a>
|
||||
template defines a whole raft of these conversions (for <code>T, T*,
|
||||
T&, std::auto_ptr<T></code>, etc.), using the same inline
|
||||
friend function technique employed by <a href=
|
||||
"http://www.boost.org/libs/utility/operators.htm">the boost operators
|
||||
library</a>.
|
||||
<p>
|
||||
Because the <code>to_python</code> and <code>from_python</code> functions
|
||||
for a user-defined class are defined by <code>
|
||||
extension_class<T></code>, it is important that an instantiation of
|
||||
<code> extension_class<T></code> is visible to any code which wraps
|
||||
a C++ function with a <code>T, T*, const T&</code>, etc. parameter or
|
||||
return value. In particular, you may want to create all of the classes at
|
||||
the top of your module's init function, then <code>def</code> the member
|
||||
functions later to avoid problems with inter-class dependencies.
|
||||
<p>
|
||||
Next: <a href="building.html">Building a Module with Boost.Python</a>
|
||||
Previous: <a href="special.html">Special Method and Operator Support</a>
|
||||
Up: <a href="index.html">Top</a>
|
||||
<p>
|
||||
© Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is" without
|
||||
express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.
|
||||
<p>
|
||||
Updated: Nov 26, 2000
|
||||
|
||||
166
doc/v2/Apr2002.html
Normal file
@@ -0,0 +1,166 @@
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
<title>Boost.Python - April 2002 Progress Report</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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">April 2002 Progress Report</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<h2>Contents</h2>
|
||||
<dl class="index">
|
||||
<dt><a href="#accomplishments">Accomplishments</a></dt>
|
||||
<dl class="index">
|
||||
<dt><a href="#arity">Arbitrary Arity Support</a></dt>
|
||||
<dt><a href="#callbacks">New Callback Interface</a></dt>
|
||||
<dt><a href="#policies">Call Policies for Construtors</a></dt>
|
||||
<dt><a href="#bugs">Real Users, Real Bugs</a></dt>
|
||||
<dt><a href="#insights">New Insights</a></dt>
|
||||
<dt><a href="#v1">Boost.Python V1 Maintenance</a></dt>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#missing">What's Missing</a></dt>
|
||||
|
||||
</dl>
|
||||
|
||||
<h2><a name="accomplishments">Accomplishments</a></h2>
|
||||
|
||||
April was a short month as far as Boost.Python was concerned, since
|
||||
the spring ISO C++ Committee Meeting (and associated vacation)
|
||||
occupied me for the 2nd half of the month. However, a suprising amount
|
||||
of work got done...
|
||||
|
||||
<h3><a name="arity">Arbitrary Arity Support</a></h3>
|
||||
|
||||
I began using the <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
|
||||
Boost.Preprocessor resulted in several improvements to the library,
|
||||
most notably in its documentation.
|
||||
|
||||
<p>
|
||||
|
||||
Boost.Python now supports calls of up to 17 arguments on most
|
||||
compilers. Because most EDG-based compilers have dismal preprocessor
|
||||
performance, I had to "manually" expand the metaprograms for
|
||||
arities from zero to fifteen arguments, and EDG-based compilers with
|
||||
<code>__EDG_VERSION__ <= 245</code> only support 15
|
||||
arguments by default. If some crazy program finds a need for more than
|
||||
the default arity support, users can increase the base support by
|
||||
setting the <code>BOOST_PYTHON_MAX_ARITY</code> preprocessor symbol.
|
||||
|
||||
<h3><a name="callbacks">New Callback Interface</a></h3>
|
||||
|
||||
I mentioned in <a href="Mar2002.html">last month's report</a> that I
|
||||
wasn't pleased with the interface for the interface for calling into
|
||||
Python, so now it has been redesigned. The new interface is outlined
|
||||
in <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-April/000953.html">this
|
||||
message</a> (though the GCC 2.95.3 bugs have been fixed).
|
||||
|
||||
<h3><a name="policies">Call Policies for Constructors</a></h3>
|
||||
|
||||
On April 2nd, I <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-April/000916.html">announced</a>
|
||||
support for the use of call policies with constructors.
|
||||
|
||||
<h3><a name="bugs">Real Users, Real Bugs</a></h3>
|
||||
|
||||
At least two people outside of Kull began actually using Boost.Python
|
||||
v2 in earnest this month. Peter Bienstman and Pearu Pearson both
|
||||
provided valuable real-world bug reports that helped me to improve the
|
||||
library's robustness.
|
||||
|
||||
<h3><a name="insights">New Insights</a></h3>
|
||||
|
||||
<a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-May/001010.html"
|
||||
>Answering some of Pearu's questions</a> about explicitly converting
|
||||
objects between Python and C++ actually led me to a new understanding
|
||||
of the role of the current conversion facilities. In Boost.Python v1,
|
||||
all conversions between Python and C++ were handled by a single family
|
||||
of functions, called <code>to_python()</code> and
|
||||
<code>from_python()</code>. Since the primary role of Boost.Python is
|
||||
to wrap C++ functions in Python, I used these names for the first kind
|
||||
of converters I needed: those that extract C++ objects to be used as
|
||||
function arguments and which C++ function return values to
|
||||
Python. The better-considered approach in Boost.Python v2 uses a
|
||||
completely different mechanism for conversions used when calling
|
||||
Python from C++, as in wrapped virtual function implementations. I
|
||||
usually think of this as a "callback", as in "calling
|
||||
back into Python", and I named the converters used in callbacks
|
||||
accordingly: <code>to_python_callback</code> and
|
||||
<code>from_python_callback</code>. However, as it turns out, the
|
||||
behavior of the "callback" converters is the appropriate one
|
||||
for users who want to explicitly extract a C++ value from a Python
|
||||
object, or create a Python object from a C++ value. The upshot is that
|
||||
it probably makes sense to change the name of the existing <code>to_python</code> and
|
||||
<code>from_python</code> so those names are available for the
|
||||
user-friendly explicit converters.
|
||||
|
||||
<p>
|
||||
<a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-May/001013.html">Another
|
||||
of Pearu's questions</a> pushes momentum further in the direction of a
|
||||
more-sophisticated overloading mechanism than the current
|
||||
simple-minded "first match" approach, as I suggested <a
|
||||
href="Mar2002.html#implicit_conversions">last month</a>.
|
||||
|
||||
<h3><a name="v1">Boost.Python V1 Maintenance</a></h3>
|
||||
|
||||
As much as I'm looking forward to retiring Boost.Python v1, a
|
||||
significant amount of effort has been being spent dealing with support
|
||||
problems; the saying that code rots when left alone is true, and
|
||||
Boost.Python is no exception. Eventually it became obvious to me that
|
||||
we were going to have to invest some effort in keeping V1 healthy
|
||||
while working on V2. Ralf and I have expanded support for various
|
||||
compilers and stabilized the V1 codebase considerably. We discarded
|
||||
the obsolete Visual Studio projects which were causing so much
|
||||
confusion. Still to do before the next Boost release:
|
||||
<ol>
|
||||
<li>Update the build/test documentation with detailed instructions for
|
||||
configuring various toolsets.
|
||||
<li>Provide some links to Boost.Python v2 to let people know what's
|
||||
coming.
|
||||
</ol>
|
||||
|
||||
|
||||
<h2><a name="missing">What's Missing</a></h2>
|
||||
|
||||
Last month I announced that I would implement the following which are
|
||||
not yet complete:
|
||||
<ol>
|
||||
<li>Document all implemented features
|
||||
<li>Implement conversions for <code>char</code> types. This is
|
||||
implemented but not tested, so we have to assume it doesn't work.
|
||||
</ol>
|
||||
|
||||
These are my first priority for this month (especially the
|
||||
documentation).
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. </i></p>
|
||||
</body>
|
||||
</html>
|
||||
165
doc/v2/CallPolicies.html
Normal file
@@ -0,0 +1,165 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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">
|
||||
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
|
||||
|
||||
<title>Boost.Python - CallPolicies Concept</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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">CallPolicies Concept</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#composition">CallPolicies Composition</a></dt>
|
||||
|
||||
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#CallPolicies-concept">CallPolicies Concept</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p>Models of the CallPolicies concept are used to specialize the behavior
|
||||
of Python callable objects generated by Boost.Python to wrapped C++
|
||||
objects like function and member function pointers, providing three
|
||||
behaviors:</p>
|
||||
|
||||
<ol>
|
||||
<li><code>precall</code> - Python argument tuple management before the
|
||||
wrapped object is invoked</li>
|
||||
|
||||
<li><code>result_converter</code> - C++ return value handling</li>
|
||||
|
||||
<li><code>postcall</code> - Python argument tuple and result management
|
||||
after the wrapped object is invoked</li>
|
||||
<li><code>extract_return_type</code> - metafunction for extracting the return type from a given signature type sequence</li>
|
||||
</ol>
|
||||
|
||||
<h2><a name="composition"></a>CallPolicies Composition</h2>
|
||||
In order to allow the use of multiple models of CallPolicies in the same
|
||||
callable object, Boost.Python's CallPolicies class templates provide a
|
||||
chaining interface which allows them to be recursively composed. This
|
||||
interface takes the form of an optional template parameter,
|
||||
<code>Base</code> which defaults to <a href=
|
||||
"default_call_policies.html#default_call_policies-spec"><code>default_call_policies</code></a>.
|
||||
By convention, the <code>precall</code> function of the <code>Base</code>
|
||||
is invoked <i>after</i> the <code>precall</code> function supplied by the
|
||||
outer template, and the <code>postcall</code> function of the
|
||||
<code>Base</code> is invoked <i>before</i> the <code>postcall</code>
|
||||
function of the outer template. If a <code>result_converter</code> is
|
||||
supplied by the outer template, it <i>replaces</i> any
|
||||
<code>result_converter</code> supplied by the <code>Base</code>. For an
|
||||
example, see <a href=
|
||||
"return_internal_reference.html#return_internal_reference-spec"><code>return_internal_reference</code></a>.
|
||||
|
||||
|
||||
<h2><a name="concept-requirements"></a>Concept Requirements</h2>
|
||||
|
||||
<h3><a name="CallPolicies-concept"></a>CallPolicies Concept</h3>
|
||||
|
||||
<p>In the table below, <code><b>x</b></code> denotes an object whose type
|
||||
<code><b>P</b></code> is a model of CallPolicies, <code><b>a</b></code>
|
||||
denotes a <code>PyObject*</code> pointing to a Python argument tuple
|
||||
object, and <code><b>r</b></code> denotes a <code>PyObject*</code>
|
||||
referring to a "preliminary" result object.</p>
|
||||
|
||||
<table summary="CallPolicies expressions" border="1" cellpadding="5">
|
||||
<tr>
|
||||
<td><b>Expression</b></td>
|
||||
|
||||
<td><b>Type</b></td>
|
||||
|
||||
<td><b>Result/Semantics</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>x.precall(a)</code></td>
|
||||
|
||||
<td>convertible to <code>bool</code></td>
|
||||
|
||||
<td>returns <code>false</code> and <code><a href=
|
||||
"http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>() != 0</code>
|
||||
upon failure, <code>true</code> otherwise.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>P::result_converter</code></td>
|
||||
|
||||
<td>A model of <a href=
|
||||
"ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>.</td>
|
||||
|
||||
<td>An MPL unary <a href=
|
||||
"../../../mpl/doc/refmanual/metafunction-class.html">Metafunction
|
||||
Class</a> used produce the "preliminary" result object.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>x.postcall(a, r)</code></td>
|
||||
|
||||
<td>convertible to <code>PyObject*</code></td>
|
||||
|
||||
<td>0 <code>0</code> and <code><a href=
|
||||
"http://www.python.org/doc/2.2/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>() != 0</code>
|
||||
upon failure. Must "conserve references" even in the event of an
|
||||
exception. In other words, if <code>r</code> is not returned, its
|
||||
reference count must be decremented; if another existing object is
|
||||
returned, its reference count must be incremented.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><code>P::extract_return_type</code></td>
|
||||
|
||||
<td>A model of <a href=
|
||||
"../../../mpl/doc/refmanual/metafunction.html">Metafunction</a>.</td>
|
||||
|
||||
<td>An MPL unary <a href=
|
||||
"../../../mpl/doc/refmanual/metafunction.html">Metafunction</a> used extract the return type from a given signature. By default it is derived from mpl::front.</td>
|
||||
</tr>
|
||||
</table>
|
||||
Models of CallPolicies are required to be <a href=
|
||||
"../../../utility/CopyConstructible.html">CopyConstructible</a>.
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
|
||||
<p>Permission to copy, use, modify, sell and distribute this software is
|
||||
granted provided this copyright notice appears in all copies. This
|
||||
software is provided "as is" without express or implied warranty, and
|
||||
with no claim as to its suitability for any purpose.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
74
doc/v2/Dereferenceable.html
Normal file
@@ -0,0 +1,74 @@
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
|
||||
<title>Boost.Python - Dereferenceable Concept</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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">Dereferenceable Concept</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#Dereferenceable-concept">Dereferenceable Concept</a></dt>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<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>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>Result</b></td>
|
||||
<td><b>Operational Semantics</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>get_pointer(x)</code></td>
|
||||
<td>convertible to <code><a href="pointee.html#pointee-spec">pointee</a><T>::type*</code>
|
||||
<td><code>&*x</code>, or a null pointer
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
</table>
|
||||
|
||||
<hr>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
18 December, 2003
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002-2003. </i>
|
||||
|
||||
<p>Permission to copy, use, modify, sell
|
||||
and distribute this software is granted provided this copyright notice appears
|
||||
in all copies. This software is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.
|
||||
</body>
|
||||
</html>
|
||||
96
doc/v2/Extractor.html
Normal file
@@ -0,0 +1,96 @@
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
|
||||
<title>Boost.Python - Extractor Concept</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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">Extractor Concept</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#Extractor-concept">Extractor Concept</a></dt>
|
||||
</dl>
|
||||
<dt><a href="#notes">Notes</a></dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p>An Extractor is a class which Boost.Python can use to extract C++
|
||||
objects from Python objects, and is typically used by facilities that
|
||||
define <code>from_python</code> conversions for
|
||||
"traditional" Python extension types.
|
||||
|
||||
<h2><a name="concept-requirements"></a>Concept Requirements</h2>
|
||||
<h3><a name="Extractor-concept"></a>Extractor Concept</h3>
|
||||
|
||||
<p>In the table below, <code><b>X</b></code> denotes a model of
|
||||
Extractor and <code><b>a</b></code> denotes an instance of a Python
|
||||
object type.
|
||||
|
||||
<table summary="Extractor expressions" border="1" cellpadding="5">
|
||||
|
||||
<tr>
|
||||
<td><b>Expression</b></td>
|
||||
<td><b>Type</b></td>
|
||||
<td><b>Semantics</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>X::execute(a)</code></td>
|
||||
<td>non-void
|
||||
<td>Returns the C++ object being extracted. The
|
||||
<code>execute</code> function must not be overloaded.
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>&a.ob_type</code>
|
||||
<td><code><a
|
||||
href="http://www.python.org/doc/2.2/ext/dnt-type-methods.html">PyTypeObject</a>**</code>
|
||||
<td>Points to the <code>ob_type</code> field of an object which is
|
||||
layout-compatible with <code>PyObject</code>
|
||||
</tr>
|
||||
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<h2><a name="notes"></a>Notes</h2>
|
||||
|
||||
Informally, an Extractor's <code>execute</code> member must be a
|
||||
non-overloaded static function whose single argument is a Python
|
||||
object type. Acceptable Python object types include those publicly (and
|
||||
unambiguously) derived from <code>PyObject</code>, and POD types which
|
||||
are layout-compatible with PyObject.
|
||||
|
||||
<hr>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. </i>
|
||||
|
||||
<p>Permission to copy, use, modify, sell
|
||||
and distribute this software is granted provided this copyright notice appears
|
||||
in all copies. This software is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.
|
||||
</body>
|
||||
</html>
|
||||
74
doc/v2/HolderGenerator.html
Normal file
@@ -0,0 +1,74 @@
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
|
||||
<title>Boost.Python - Holder Concept</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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">HolderGenerator Concept</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#HolderGenerator-concept">HolderGenerator Concept</a></dt>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p>A HolderGenerator is a unary metafunction class which returns types
|
||||
suitable for holding instances of its argument in a wrapped C++ class
|
||||
instance.
|
||||
|
||||
<h2><a name="concept-requirements"></a>Concept Requirements</h2>
|
||||
<h3><a name="HolderGenerator-concept"></a>HolderGenerator Concept</h3>
|
||||
|
||||
<p>In the table below, <code><b>G</b></code> denotes an type which
|
||||
models HolderGenerator, and <code><b>X</b></code> denotes a class
|
||||
type.
|
||||
|
||||
<table summary="Holder expressions" border="1" cellpadding="5">
|
||||
|
||||
<tr>
|
||||
<td><b>Expression</b></td>
|
||||
<td><b>Requirements</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>G::apply<X>::type</code></td>
|
||||
<td>A concrete subclass of <a
|
||||
href="instance_holder.html#instance_holder-spec">instance_holder</a>
|
||||
which can hold objects of type <code>X</code>.
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<hr>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. </i>
|
||||
|
||||
<p>Permission to copy, use, modify, sell
|
||||
and distribute this software is granted provided this copyright notice appears
|
||||
in all copies. This software is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.
|
||||
</body>
|
||||
</html>
|
||||
229
doc/v2/Jun2002.html
Normal file
@@ -0,0 +1,229 @@
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
<title>Boost.Python - June 2002 Progress Report</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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">June 2002 Progress Report</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<h2>Contents</h2>
|
||||
<dl class="index">
|
||||
<dt><a href="#intro">Introduction</a></dt>
|
||||
<dt><a href="#handle"><code>handle<T></code></a></dt>
|
||||
<dt><a href="#object"><code>object</code></a></dt>
|
||||
<dl class="index">
|
||||
<dt><a href="#operators"><code>object</code> operators</a></dt>
|
||||
<dt><a href="#conversions"><code>object</code> conversions</a></dt>
|
||||
</dl>
|
||||
<dt><a href="#list"><code>list</code></a></dt>
|
||||
<dt><a href="#numerics"><code>Numerics</code></a></dt>
|
||||
<dt><a href="#community">Community</a></dt>
|
||||
<dt><a href="#next">What's Next</a></dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="intro">Introduction</a></h2>
|
||||
|
||||
July was mostly focused on allowing expressive manipulation of
|
||||
individual Python objects, or what Ralf Grosse-Kunstleve calls
|
||||
"Writing Python in C++". The work began with this <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-June/001311.html">posting</a>,
|
||||
which outlines the issues and intention.
|
||||
|
||||
<h2><a name="handle"><code>handle<T></code></a></h2>
|
||||
|
||||
The most basic element needed was a replacement for the
|
||||
<code>reference<></code> class template and the
|
||||
<code>ref</code> typedef from Boost.Python v1, a simple smart
|
||||
pointer to a Python object. The old v1 typedef
|
||||
"<code>ref</code>" (for
|
||||
<code>reference<PyObject></code>) had to be retired because I
|
||||
thought it would be too confusing given the importance of <code><a
|
||||
href="../../../bind/ref.html">boost::ref</a>()</code> to this
|
||||
library. I began a <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-June/001311.html">discussion</a>of
|
||||
possible names, and it was eventually <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-June/001337.html">decided</a>
|
||||
to rename <code>reference</code> to <code>handle</code> and supply a
|
||||
default argument so that <code>ref</code> could be spelled
|
||||
<code>handle<></code> without an additional typedef. There
|
||||
were also some interface changes to make it safer and more-efficient
|
||||
to interface with the raw
|
||||
<code>PyObject*</code>s forced on us by Python's 'C' API. A
|
||||
discussion of those protocols can be found <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-June/001401.html">here</a>.
|
||||
|
||||
<h2><a name="handle"><code>object</code></a></h2>
|
||||
|
||||
It is intended that users will seldom need or want to work with
|
||||
<code>handle<></code>; its major distinguishing features are
|
||||
that it gives direct access to the underlying object representation
|
||||
through <code>operator*</code> and <code>operator-></code>, and
|
||||
that can be <code>NULL</code>, both sources of danger. Instead the
|
||||
library provides a class called <code>object</code>, which
|
||||
encapsulates a valid Python object and provides a similar interface to
|
||||
Python's.
|
||||
|
||||
<h3><a name="operators"><code>object</code> operators</a></h3>
|
||||
|
||||
The first challenge was to provide support for object manipulations
|
||||
using a Python-like syntax, mostly in the form of operator overloads:
|
||||
|
||||
<table border="1">
|
||||
<tr><th>Python <th>C++
|
||||
|
||||
<tr>
|
||||
<td><code>y = x.foo</code> <td><code>y = x.attr("foo");
|
||||
<tr>
|
||||
<td><code>x.foo = 1</code> <td><code>x.attr("foo") = 1;
|
||||
|
||||
<tr>
|
||||
<td><code>y = x[z]</code> <td><code>y = x[z];
|
||||
<tr>
|
||||
<td><code>x[z] = 1</code> <td><code>x[z] = 1;
|
||||
|
||||
<tr>
|
||||
<td><code>y = x[3:-1]</code> <td><code>y = x.slice(3,-1);
|
||||
|
||||
<tr>
|
||||
<td><code>y = x[3:]</code> <td><code>y = x.slice(3,_);
|
||||
|
||||
<tr>
|
||||
<td><code>y = x[:-2]</code> <td><code>y = x.slice(_,-2);
|
||||
|
||||
<tr>
|
||||
<td><code>z = x(1, y)</code> <td><code>z = x(1, y);
|
||||
<tr>
|
||||
<td><code>z = x.f(1, y)</code> <td><code>z = x.attr("f")(1, y);
|
||||
|
||||
<tr>
|
||||
<td><code>not x</code> <td><code>!x
|
||||
|
||||
<tr>
|
||||
<td><code>x and y</code> <td><code>x and y
|
||||
</table>
|
||||
|
||||
I'm still a unsatisfied with the interface for attribute access. There
|
||||
original proposal used a syntax like this one:
|
||||
<pre>
|
||||
y = x._("foo");
|
||||
x._("foo") = 1;
|
||||
</pre>
|
||||
|
||||
which was only marginally better than what we've got. Niki Spahiev
|
||||
then <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-June/001447.html">pointed
|
||||
out</a> a potential conflict with the macro which GNU Gettext <a
|
||||
href="http://www.gnu.org/manual/gettext/html_mono/gettext.html#SEC6">suggests</a>
|
||||
people define. This unfortunate state of affairs forced us into using
|
||||
<code>attr</code> instead. I'd still like to find a better interface,
|
||||
but the lack of overloadable C++ operators which aren't already used
|
||||
in Python is an obstacle. The comma operator is still a possibility,
|
||||
but it has the wrong precedence:
|
||||
<pre>
|
||||
y = x,"foo" // error
|
||||
x,"foo" = 1; // error
|
||||
|
||||
y = (x,"foo"); // ok
|
||||
(x,"foo") = 1; // ok
|
||||
</pre>
|
||||
|
||||
Well, I guess we could consider adding that to the interface without
|
||||
removing <code>attr()</code>, to see how it plays out...
|
||||
|
||||
<h3><a name="operators"><code>object</code> conversions</a></h3>
|
||||
|
||||
The <code>object</code> class also provided an opportunity to replace
|
||||
Boost.Python v1's <code>to_python()</code> as a user-level
|
||||
interface. Instead, <code>object</code> has a templated constructor
|
||||
which can be used to convert any C++ object to Python using the same
|
||||
underlying mechanisms used for the arguments to <code><a
|
||||
href="call.html">call</a><></code>.
|
||||
|
||||
<p>Incidentally, the implementation of operator and conversion support
|
||||
for object uncovered an inordinate number of compiler bugs in our
|
||||
targeted platforms. It was a lot more "interesting" than it
|
||||
should have been.
|
||||
|
||||
<h2><a name="list"><code>list</code></a></h2>
|
||||
|
||||
With <code>object</code> implemented, it was time to begin replacing
|
||||
the ad-hoc implementations of <code>list</code>, <code>string</code>,
|
||||
and <code>dictionary</code> supplied by Boost.Python v1 with something
|
||||
more robust. I started with <code>list</code> as an example. Because
|
||||
<code>object</code> already provides all of the requisite operators,
|
||||
publicly deriving <code>list</code> from object seemed like a good
|
||||
choice. The remaining issues were what do do about the one-argument
|
||||
list constructor (which in Python attempts to convert its argument to
|
||||
a list), and how to deal converting with <code>list</code> arguments
|
||||
to wrapped functions. Some of the issues are laid out in <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-June/001551.html">this
|
||||
thread</a>. Ultimately, it was decided that <code>list(x)</code>
|
||||
should do the same thing in C++ as in Python (conversion), while
|
||||
<code>list</code> arguments should only match Python
|
||||
<code>list</code>s (and <code>list</code> subclasses). The
|
||||
implementation worked well, and provided a <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-June/001586.html">roadmap</a>
|
||||
for the protocol to be used for implementation of the other built-in
|
||||
types.
|
||||
|
||||
<h2><a name="numerics">Numerics</a></h2>
|
||||
|
||||
Support for C++ <code>long long</code> and <code>unsigned long
|
||||
long</code>
|
||||
(and <code>__int64</code> on MSVC) to/from python conversions was
|
||||
added this month. We also improved handling of numeric overflows when
|
||||
converting, e.g., a Python int to a type with a more limited range of
|
||||
representation.
|
||||
|
||||
<h2><a name="community">Community</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>Ralf W. Grosse-Kunstleve and Nick Sauter have implemented
|
||||
<a href="http://cci.lbl.gov/boost/">multiplatform nightly
|
||||
build-and-test</a> runs for Boost.Python V2 at LBL.
|
||||
|
||||
<li>Dave Hawkes has made significant progress on generating the
|
||||
Python <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-June/001503.html">built-in
|
||||
function and API wrappers</a>
|
||||
|
||||
<li>Achim Domma has agreed to take up the job of implementing the
|
||||
<code>str</code>, <code>dict</code>, and <code>tuple</code> classes.
|
||||
</ul>
|
||||
|
||||
Deep thanks to all the Boost.Python contributors! This project
|
||||
wouldn't be possible without your participation.
|
||||
|
||||
<h2><a name="next">What's Next</a></h2>
|
||||
|
||||
As I write this we are already well into the month of July, so I
|
||||
suggest you consult the <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-July/">Mailing
|
||||
List Archive</a> if you want to know what's been happening. Otherwise
|
||||
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 -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. </i></p>
|
||||
</body>
|
||||
</html>
|
||||
237
doc/v2/Mar2002.html
Normal file
@@ -0,0 +1,237 @@
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
<title>Boost.Python - March 2002 Progress Report</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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">March 2002 Progress Report</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<h2>Contents</h2>
|
||||
<dl class="index">
|
||||
<dt><a href="#accomplishments">Accomplishments</a></dt>
|
||||
<dl class="index">
|
||||
<dt><a href="#calling_python">Calling Python from C++</a></dt>
|
||||
<dt><a href="#virtual_functions">Virtual Functions</a></dt>
|
||||
<dt><a href="#abstract_classes">Abstract Classes</a></dt>
|
||||
<dt><a href="#implicit_conversions">C++ Implicit Conversions</a></dt>
|
||||
<dt><a href="#data_members">C++ Data Members</a></dt>
|
||||
<dt><a href="#miscellaneous">Miscellaneous</a></dt>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#future">The Near future</a></dt>
|
||||
|
||||
<dt><a href="#notes">Notes</a></dt>
|
||||
|
||||
</dl>
|
||||
|
||||
<h2><a name="accomplishments">Accomplishments</a></h2>
|
||||
|
||||
March was mostly devoted to the reimplementation of features from
|
||||
Boost.Python v1, and some new features. Re-examination of the features
|
||||
from Boost.Python v1 allowed me to make significant improvements.
|
||||
|
||||
<h3><a name="calling_python">Calling Python from C++</a></h3>
|
||||
|
||||
The ability to call Python from C++ is crucial for virtual function
|
||||
support. Implementing this feature well for V2 proved to be more
|
||||
interesting than I expected. You can review most of the relevant
|
||||
design decisions
|
||||
<a href="callbacks.txt">here</a>.
|
||||
|
||||
<p>
|
||||
One point which <i>isn't</i> emphasized in that document is that there
|
||||
are subtle differences in the way <code>from_python</code> conversions
|
||||
work when used for C++ function arguments and Python function return
|
||||
values. In particular, while <code>T const&</code> arguments may
|
||||
invoke rvalue converters, a reference-to-const return value requires
|
||||
an lvalue converter, since a temporary conversion result would leave
|
||||
the returned reference dangling.
|
||||
|
||||
<p>I'm not particularly pleased with the current callback interface,
|
||||
since it usually results in constructs like:
|
||||
<pre>
|
||||
<u>return returning</u><X&>::call(f, obj);
|
||||
</pre>
|
||||
However, I think the following may be possible and I plan to investigate:
|
||||
<pre>
|
||||
return apply<X&>(f, obj);
|
||||
</pre>
|
||||
I'm open to suggestion for better names (and syntaxes)!
|
||||
|
||||
<h3><a name="virtual_functions">Virtual Functions</a></h3>
|
||||
|
||||
Once Python callbacks were implemented, it was just a short step to
|
||||
implementing virtual functions. Python extension class exposing a C++
|
||||
class whose virtual functions are overridable in Python must actually
|
||||
hold a C++ instance of a class <i>derived</i> from the one exposed to
|
||||
Python. Needing some way for users to specify that class, I added an
|
||||
optional template argument to <code>value_holder_generator</code> and
|
||||
<code>pointer_holder_generator<></code> to specify the class
|
||||
actually held. This move began to put pressure on the
|
||||
<code>class_<></code> interface, since the need for the user to
|
||||
produce complicated instantations of
|
||||
<code>class_<></code> was increased:
|
||||
|
||||
<pre>
|
||||
class<Foo, bases<>, value_holder_generator<Foo_callback> >("Foo")
|
||||
.def("hello", &Foo::hello)
|
||||
...
|
||||
</pre>
|
||||
|
||||
<h3><a name="abstract_classes">Abstract Classes</a></h3>
|
||||
|
||||
Normally when a C++ class is exposed to Python, the library registers
|
||||
a conversion function which allows users to wrap functions returning
|
||||
values of that type. Naturally, these return values are temporaries,
|
||||
so the conversion function must make a copy in some
|
||||
dynamically-allocated storage (a "holder") which is managed
|
||||
by the corresponding Python object.
|
||||
|
||||
<p>Unfortunately, in the case of abstract classes (and other types
|
||||
without a publicly-accessible copy constructor), instantiating this
|
||||
conversion function causes a compilation error. In order to support
|
||||
non-copyable classes, there had to be some way to prevent the library
|
||||
from trying to instantiate the conversion function. The only practical
|
||||
approach I could think of was to add an additional template parameter
|
||||
to the <code>class_<></code> interface. When the number of
|
||||
template parameters with useful defaults begins to grow, it is often
|
||||
hard to choose an order which allows users to take advantage of the
|
||||
defaults.
|
||||
|
||||
<p>
|
||||
|
||||
This was the straw that broke the
|
||||
<code>class_<></code> interface's back and caused the redesign
|
||||
whose outcome is detailed <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-March/000892.html">here</a>.
|
||||
The approach allows the user to supply the optional parameters in an
|
||||
arbitrary order. It was inspired by the use of <a
|
||||
href="../../../utility/iterator_adaptors.htm#named_tempalte_parameters">named
|
||||
template parameters</a> in the <a
|
||||
href="../../../utility/iterator_adaptors.htm">Boost Iterator Adaptor
|
||||
Library</a>, though in this case it is possible to deduce the meaning
|
||||
of the template parameters entirely from their type properties,
|
||||
resulting in a simpler interface. Although the move from a
|
||||
policy-based design to what resembles a configuration DSL usually
|
||||
implies a loss of flexibility, in this case I think any costs are far
|
||||
outweighed by the advantages.
|
||||
|
||||
<p>Note: working around the limitations of the various compilers I'm
|
||||
supporting was non-trivial, and resulted in a few messy implementation
|
||||
details. It might be a good idea to switch to a more-straightforward
|
||||
approach once Metrowerks CodeWarrior Pro8 is released.
|
||||
|
||||
<h3><a name="implicit_conversions">C++ Implicit Conversions</a></h3>
|
||||
|
||||
Support for C++ implicit conversion involves creating
|
||||
<code>from_python</code> converters for a type <code>U</code> which in
|
||||
turn use <code>from_python</code> converters registered for a type
|
||||
<code>T</code> where there exists a implicit conversion from
|
||||
<code>T</code> to <code>U</code>. The current implementation is
|
||||
subject to two inefficiencies:
|
||||
<ol>
|
||||
|
||||
<li>Because an rvalue <code>from_python</code> converter produces two
|
||||
pieces of data (a function and a <code>void*</code>) from its
|
||||
<code>convertible()</code> function, we end up calling the function
|
||||
for <code>T</code> twice: once when the converter is looked up in the
|
||||
registry, and again when the conversion is actually performed.
|
||||
|
||||
<li>A vector is used to mark the "visited" converters, preventing
|
||||
infinite recursion as <code>T</code> to
|
||||
<code>U</code> and <code>U</code> to <code>T</code> converters
|
||||
continually search through one-another.
|
||||
|
||||
</ol>
|
||||
|
||||
I consider the former to be a minor issue. The second may or may not
|
||||
prove to be computationally significant, but I believe that
|
||||
architecturally, it points toward a need for more sophisticated
|
||||
overload resolution. It may be that we want CLOS-style multimethod
|
||||
dispatching along with C++ style rules that prevent more than one
|
||||
implicit conversion per argument.
|
||||
|
||||
<h3><a name="data_members">C++ Data Members</a></h3>
|
||||
|
||||
To supply the ability to directly access data members, I was able to
|
||||
hijack the new Python <a
|
||||
href="http://www.python.org/2.2/descrintro.html#property">property</a>
|
||||
type. I had hoped that I would also be able to re-use the work of <a
|
||||
href="make_function.html">make_function</a> to create callable python
|
||||
objects from C++ functions which access a data member of a given
|
||||
class. C++ facilities for specifying data member pointer non-type
|
||||
template arguments require the user to explicitly specify the type of
|
||||
the data member and this under-utilized feature is also not
|
||||
well-implemented on all compilers, so passing the member pointer as a
|
||||
runtime value is the only practical approach. The upshot is that any
|
||||
such entity would actually have to be a function <i>object</i>, and I
|
||||
haven't implemented automatic wrapping of C++ callable function
|
||||
objects yet, so there is less re-use in the implementation than I'd
|
||||
like. I hope to implement callable object wrapping and refactor this
|
||||
code one day. I also hope to implement static data member support,
|
||||
for which Python's property will not be an appropriate descriptor.
|
||||
|
||||
<h3><a name="miscellaneous">Miscellaneous</a></h3>
|
||||
<ul>
|
||||
<li>Moved <code>args<></code> and <code>bases<></code> from unnamed namespace to <code>boost::python</code> in their own header files.
|
||||
<li>Convert <code>NULL</code> pointers returned from wrapped C++ functions to <code>None</code>.
|
||||
<li>Improved some compile-time error checks.
|
||||
<li>Eliminated <code>boost/python/detail/eval.hpp</code> in favor of
|
||||
more-general <code>boost/mpl/apply.hpp</code>.
|
||||
<li>General code cleanup and refactoring.
|
||||
<li>Works with Microsoft Visual C++ 7.0
|
||||
<li>Warning suppression for many compilers
|
||||
<li>Elegant interface design for exporting <code>enum</code> types.
|
||||
</ul>
|
||||
<hr>
|
||||
|
||||
<h2><a name="future">The Near Future</a></h2>
|
||||
|
||||
Before April 15th I plan to
|
||||
<ol>
|
||||
<li>Document all implemented features
|
||||
<li>Implement a <code>CallPolicy</code> interface for constructors of wrapped
|
||||
classes
|
||||
<li>Implement conversions for <code>char</code> types.
|
||||
<li>Implement automated code generation for all headers containing
|
||||
families of overloaded functions to handle arbitrary arity.
|
||||
</ol>
|
||||
|
||||
I also hope to implement a mechanism for generating conversions
|
||||
between arbitrary Python sequences and C++ containers, if time permits
|
||||
(and others haven't already done it)!
|
||||
|
||||
<h2><a name="notes">Notes</a></h2>
|
||||
|
||||
The older version of KCC used by Kull is generating lots of warnings
|
||||
about a construct I use to instantiate static members of various class
|
||||
templates. I'm thinking of moving to an idiom which uses a function
|
||||
template to suppress it, but worry about bloating the size of debug
|
||||
builds. Since KCC users may be moving to GCC, I'm not sure that it's
|
||||
worth doing anything about it.
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. </i></p>
|
||||
</body>
|
||||
</html>
|
||||
311
doc/v2/May2002.html
Normal file
@@ -0,0 +1,311 @@
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
<title>Boost.Python - May 2002 Progress Report</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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">May 2002 Progress Report</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<h2>Contents</h2>
|
||||
<dl class="index">
|
||||
<dt><a href="#intro">Introduction</a></dt>
|
||||
<dt><a href="#features">New Features</a></dt>
|
||||
<dl>
|
||||
<dt><a href="#aix_shared">Shared Library Support for AIX</a><dd>
|
||||
<dt><a href="#class_enhancements">Class Enhancements</a><dd>
|
||||
<dl>
|
||||
<dt><a href="#operators">Operators</a><dd>
|
||||
<dt><a href="#iterators">Iterators</a><dd>
|
||||
<dt><a href="#properties">Properties</a><dd>
|
||||
<dt><a href="#setattr">setattr</a><dd>
|
||||
<dt><a href="#module">__module__ Attribute</a><dd>
|
||||
</dl>
|
||||
<dt><a href="#back_reference">back_reference</a><dd>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#documentation">Documentation</a></dt>
|
||||
<dt><a href="#misc">Miscellaneous</a></dt>
|
||||
<dl class="index">
|
||||
<dt><a href="#converters">Converters</a></dt>
|
||||
<dt><a href="#checkins">Checkins Mailing List</a></dt>
|
||||
<dt><a href="#shared">Shared Libraries</a></dt>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#next">What's Next</a></dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="intro">Introduction</a></h2>
|
||||
|
||||
Aside from library development, work on Boost.Python in May was
|
||||
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/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>.
|
||||
|
||||
<h2><a name="features">New Features</a></h2>
|
||||
|
||||
<h3><a name="aix_shared">Shared Library Support for AIX</a></h3>
|
||||
|
||||
The Kull group required the ability to build and test Boost.Python
|
||||
extensions on AIX, a platform with "creatively designed"
|
||||
shared library semantics. Making this work was a multi-pronged
|
||||
effort, involving changes to Boost.Build and some great research by
|
||||
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/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
|
||||
solution is surely possible. Linking on AIX is sufficiently
|
||||
interesting to have skewed the Boost.Python development schedule a
|
||||
bit.
|
||||
|
||||
<h3><a name="class_enhancements">Class Enhancements</a></h3>
|
||||
|
||||
<h4><a name="operators">Operators</a></h4>
|
||||
|
||||
Support for exposing C++ operators and functions as the corresponding
|
||||
Python special methods was added. Thinking that the Boost.Python
|
||||
v1 interface was a little too esoteric (especially the use of
|
||||
<code>left_operand<...>/right_operand<...></code> for
|
||||
asymmetric operands), I introduced a simple form of <a
|
||||
href="http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html">expression
|
||||
templates</a> which allow users to simply write the expressions that
|
||||
should be wrapped, as in this <a href="operators.html#examples">example</a>.
|
||||
|
||||
<h4><a name="iterators">Iterators</a></h4>
|
||||
|
||||
Python iterator support as required by the Kull project resulted in a
|
||||
highly flexible interface allowing:
|
||||
|
||||
<dl>
|
||||
|
||||
<dt>Direct exposure of a class' <code>begin()</code> and
|
||||
<code>end()</code> functions:
|
||||
|
||||
<pre>
|
||||
...
|
||||
.def("__iter__", iterator<list_int>())
|
||||
</pre>
|
||||
<dd>
|
||||
|
||||
<dt>Creation of iterators from member functions...
|
||||
<pre>
|
||||
...
|
||||
.def("__iter__"
|
||||
, range(&my_class::x_begin, &my_class::x_end))
|
||||
)
|
||||
</pre>
|
||||
<dd>
|
||||
|
||||
<dt>...and member data:
|
||||
<pre>
|
||||
...
|
||||
.def("__iter__"
|
||||
, range(&std::pair<char*,char*>::first, &std::pair<char*,char*>::second))
|
||||
)
|
||||
</pre>
|
||||
<dd>
|
||||
|
||||
<dt>The ability to specify <a
|
||||
href="CallPolicies.html">CallPolicies</a>, e.g. to prevent copying of
|
||||
heavyweight values:
|
||||
|
||||
<pre>
|
||||
...
|
||||
.def("__iter__",
|
||||
, range<return_value_policy<copy_non_const_reference> >(
|
||||
&my_sequence<heavy>::begin
|
||||
, &my_sequence<heavy>::end))
|
||||
</pre>
|
||||
<dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<h4><a name="properties">Properties</a></h4>
|
||||
|
||||
The Kull iteration interfaces also required the ability to iterate
|
||||
over a sequence specified by an instance's attribute:
|
||||
<pre>
|
||||
>>> f = field()
|
||||
>>> for e in f.elements:
|
||||
... print e,
|
||||
</pre>
|
||||
|
||||
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.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.
|
||||
|
||||
<h4><a name="setattr">setattr</a></h4>
|
||||
|
||||
<code>class_<></code> acquired a <code>setattr</code> member
|
||||
function which allows users to easily add new Python objects as class
|
||||
attributes.
|
||||
|
||||
<h4><a name="module">__module__ Attribute</a></h4>
|
||||
|
||||
Ralf Grosse-Kunstleve has been working on pickling support for v2. To
|
||||
make it work correctly, he had to make sure that a class'
|
||||
<code>__module__</code> attribute was set correctly.
|
||||
|
||||
<h3><a name="back_reference"><code>back_reference</code></a></h3>
|
||||
|
||||
The new <code>back_reference<T></code> template can be used as a
|
||||
function parameter when the user needs access to both a <code>T</code>
|
||||
argument and to the Python object which manages it. The function will
|
||||
only match in the overload resolution process if it would match the
|
||||
same function signature with <code>T</code> substituted for
|
||||
<code>back_reference<T></code>. This feature is not yet
|
||||
documented.
|
||||
|
||||
<h2><a name="documentation">Documentation</a></h2>
|
||||
|
||||
In a major effort to prepare Boost.Python v2 to replace v1, many pages
|
||||
of new reference documentation were added:
|
||||
|
||||
<blockquote>
|
||||
|
||||
<dl>
|
||||
<dt><a href="CallPolicies.html">CallPolicies.html</a><dd>
|
||||
<dt><a href="Dereferenceable.html">Dereferenceable.html</a><dd>
|
||||
<dt><a href="Extractor.html">Extractor.html</a><dd>
|
||||
<dt><a href="HolderGenerator.html">HolderGenerator.html</a><dd>
|
||||
<dt><a href="ResultConverter.html">ResultConverter.html</a><dd>
|
||||
<dt><a href="call_method.html">call_method.html</a><dd>
|
||||
<dt><a href="callbacks.html">callbacks.html</a><dd>
|
||||
<dt><a href="data_members.html">data_members.html</a><dd>
|
||||
<dt><a href="has_back_reference.html">has_back_reference.html</a><dd>
|
||||
<dt><a href="implicit.html">implicit.html</a><dd>
|
||||
<dt><a href="instance_holder.html">instance_holder.html</a><dd>
|
||||
<dt><a href="operators.html">operators.html</a><dd>
|
||||
<dt><a href="ptr.html">ptr.html</a><dd>
|
||||
<dt><a href="type_id.html">type_id.html</a><dd>
|
||||
<dt><a href="with_custodian_and_ward.html">with_custodian_and_ward.html</a><dd>
|
||||
</dl>
|
||||
|
||||
</blockquote>
|
||||
Major updates were made to the following pages:
|
||||
|
||||
|
||||
<blockquote>
|
||||
<dl>
|
||||
<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>
|
||||
</blockquote>
|
||||
|
||||
As usual, careful documentation forces one to consider the
|
||||
interface again, and there were many interface changes
|
||||
associated with this effort, including the elevation of the
|
||||
following components from implementation detail to
|
||||
first-class library citizen:
|
||||
|
||||
<blockquote>
|
||||
<dl>
|
||||
<dt>type_id.hpp<dd>
|
||||
<dt>pointee.hpp<dd>
|
||||
<dt>lvalue_from_pytype.hpp<dd></dl>
|
||||
</dl>
|
||||
</blockquote>
|
||||
|
||||
<h2><a name="misc">Miscellaneous</a></h2>
|
||||
|
||||
<h3><a name="converters">Converters</a></h3>
|
||||
|
||||
It appears that the world of C++ <==> Python conversion rules is
|
||||
an endlessly-rich area of exploration. Completing the conversions for
|
||||
<code>char</code> and <code>char const*</code> types, as described at
|
||||
the end of <a href="Apr2002.html#missing">April's report</a>,
|
||||
uncovered some interesting new shades to the problem. It turns out to
|
||||
be worth distinguishing mutable and immutable lvalue conversions,
|
||||
because despite the fact that Python doesn't understand
|
||||
<code>const</code>, it does understand immutability (c.f. Python
|
||||
strings, which expose an immutable <code>char</code> pointer). It is
|
||||
also worth recognizing types which represent lvalue <i>sequences</i>,
|
||||
to prevent Python <code>"foobar"</code> from being silently
|
||||
truncated to C++ <code>'f'</code>. More details on this insight can be
|
||||
found in the mailing list <a
|
||||
href="http://mail.python.org/pipermail/c++-sig/2002-May/001023.html">
|
||||
archive</a>. I don't plan to do anything about this immediately, but I
|
||||
do think it's the right direction to go in the long run.
|
||||
|
||||
<h3><a name="checkins">Checkins Mailing List</a></h3>
|
||||
|
||||
In order to better coordinate changes made by multiple developers, I
|
||||
enabled <a
|
||||
href="http://sourceforge.net/docman/display_doc.php?docid=772&group_id=1">syncmail</a>
|
||||
for the Boost.Python CVS trees, and established an associated <a
|
||||
href="http://lists.sourceforge.net/lists/listinfo/boost-python-cvs">mailing
|
||||
list</a>. Subscribe to this list to receive notices of each new
|
||||
checkin.
|
||||
|
||||
<h3><a name="shared">Shared Libraries</a></h3>
|
||||
|
||||
Beyond the vagaries of dynamic linking on AIX, I have been
|
||||
participating in a more-general discussion of dynamic linking for
|
||||
C++. Needless to say, C++ dynamic linking is of critical importance to
|
||||
Boost.Python: all extension modules are normally built as shared
|
||||
libraries, and Boost.Python extension modules share a common library
|
||||
as well.
|
||||
|
||||
In fact, there are at least two separate conversations. One
|
||||
in the C++ standard extensions mailing list concerns what can be
|
||||
standardized for C++ and shared libraries; the other, mostly on the <a
|
||||
href="http://gcc.gnu.org/ml/gcc/">gcc</a> mailing list, concerns the
|
||||
behavior of GCC on Posix/ELF platforms.
|
||||
|
||||
Some of the GCC threads are here:
|
||||
|
||||
<blockquote>
|
||||
<a
|
||||
href="http://gcc.gnu.org/ml/gcc/2002-05/msg02002.html">http://gcc.gnu.org/ml/gcc/2002-05/msg02002.html</a><br>
|
||||
<a
|
||||
href="http://gcc.gnu.org/ml/gcc/2002-05/msg02945.html">http://gcc.gnu.org/ml/gcc/2002-05/msg02945.html</a><br>
|
||||
<a href="http://gcc.gnu.org/ml/gcc/2002-05/msg01758.html">http://gcc.gnu.org/ml/gcc/2002-05/msg01758.html</a>
|
||||
</blockquote>
|
||||
|
||||
<h2><a name="next">What's Next</a></h2>
|
||||
|
||||
Development is focused on what's needed to be able to retire
|
||||
Boost.Python v1. At the moment, that means deciding the user-friendly
|
||||
interfaces for to_/from_python conversion, and formally exposing the
|
||||
Python object smart pointers and object wrapper classes. Quite a few
|
||||
questions have also been showing up recently about how to embed Python
|
||||
with Boost.Python, and how to link with it statically; the solutions
|
||||
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 -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. </i></p>
|
||||
</body>
|
||||
</html>
|
||||
153
doc/v2/ObjectWrapper.html
Normal file
@@ -0,0 +1,153 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - ObjectWrapper Concept</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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">ObjectWrapper and TypeWrapper Concepts</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#ObjectWrapper-concept">ObjectWrapper Concept</a></dt>
|
||||
|
||||
<dt><a href="#TypeWrapper-concept">TypeWrapper Concept</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#caveat">Caveat</a></dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p>This page defines two concepts used to describe classes which manage a
|
||||
Python objects, and which are intended to support usage with a
|
||||
Python-like syntax.</p>
|
||||
|
||||
<h2><a name="concept-requirements"></a>Concept Requirements</h2>
|
||||
|
||||
<h3><a name="ObjectWrapper-concept"></a>ObjectWrapper Concept</h3>
|
||||
Models of the ObjectWrapper concept have <a href=
|
||||
"object.html#object-spec">object</a> as a publicly-accessible base class,
|
||||
and are used to supply special construction behavior and/or additional
|
||||
convenient functionality through (often templated) member functions.
|
||||
Except when the return type <code>R</code> is itself an <a href=
|
||||
"#TypeWrapper-concept">TypeWrapper</a>, a member function invocation of
|
||||
the form
|
||||
<pre>
|
||||
x.<i>some_function</i>(<i>a<small>1</small>, a<small>2</small>,...a<small>n</small></i>)
|
||||
</pre>
|
||||
always has semantics equivalent to:
|
||||
<pre>
|
||||
<a href=
|
||||
"extract.html#extract-spec">extract</a><R>(x.attr("<i>some_function</i>")(<a
|
||||
href=
|
||||
"object.html#object-spec-ctors">object</a>(<i>a<small>1</small></i>), <a
|
||||
href=
|
||||
"object.html#object-spec-ctors">object</a>(<i>a<small>2</small></i>),...<a
|
||||
href="object.html#object-spec-ctors">object</a>(<i>a<small>n</small></i>)))()
|
||||
</pre>
|
||||
When the <code>R</code> is an <a href=
|
||||
"#TypeWrapper-concept">TypeWrapper</a>, the result type may be
|
||||
constructed by taking direct posession of:
|
||||
<pre>
|
||||
x.attr("<i>some_function</i>")(<a href=
|
||||
"object.html#object-spec-ctors">object</a>(<i>a<small>1</small></i>), <a
|
||||
href=
|
||||
"object.html#object-spec-ctors">object</a>(<i>a<small>2</small></i>),...<a
|
||||
href=
|
||||
"object.html#object-spec-ctors">object</a>(<i>a<small>n</small></i>)).ptr()
|
||||
</pre>
|
||||
[see <a href="#caveat">caveat</a> below]
|
||||
|
||||
<h3><a name="TypeWrapper-concept"></a>TypeWrapper Concept</h3>
|
||||
TypeWrapper is a refinement of ObjectWrapper which is associated with a
|
||||
particular Python type <code>X</code>. For a given TypeWrapper
|
||||
<code>T</code>, a valid constructor expression
|
||||
<pre>
|
||||
T(<i>a<small>1</small>, a<small>2</small>,...a<small>n</small></i>)
|
||||
</pre>
|
||||
builds a new <code>T</code> object managing the result of invoking
|
||||
<code>X</code> with arguments corresponding to
|
||||
<pre>
|
||||
<a href=
|
||||
"object.html#object-spec-ctors">object</a>(<i>a<small>1</small></i>), <a
|
||||
href=
|
||||
"object.html#object-spec-ctors">object</a>(<i>a<small>2</small></i>),...<a
|
||||
href=
|
||||
"object.html#object-spec-ctors">object</a>(<i>a<small>n</small></i>)
|
||||
</pre>
|
||||
|
||||
When used as arguments to wrapped C++ functions, or as the template
|
||||
parameter to <code><a
|
||||
href="extract.html#extract-spec">extract</a><></code>, only
|
||||
instances of the associated Python type will be considered a match.
|
||||
|
||||
<h3><a name="caveat">Caveat</a></h3>
|
||||
The upshot of the special member function invocation rules when the
|
||||
return type is a TypeWrapper is that it is possible for the returned
|
||||
object to manage a Python object of an inappropriate type. This is not
|
||||
usually a serious problem; the worst-case result is that errors will be
|
||||
detected at runtime a little later than they might otherwise be. For an
|
||||
example of how this can occur, note that the <code><a href=
|
||||
"dict.html#dict-spec">dict</a></code> member function <code>items</code>
|
||||
returns an object of type <code><a href=
|
||||
"list.html#list-spec">list</a></code>. Now suppose the user defines this
|
||||
<code>dict</code> subclass in Python:
|
||||
<pre>
|
||||
>>> class mydict(dict):
|
||||
... def items(self):
|
||||
... return tuple(dict.items(self)) # return a tuple
|
||||
</pre>
|
||||
Since an instance of <code>mydict</code> is also an instance of
|
||||
<code>dict</code>, when used as an argument to a wrapped C++ function,
|
||||
<code><a href="dict.html#dict-spec">boost::python::dict</a></code> can
|
||||
accept objects of Python type <code>mydict</code>. Invoking
|
||||
<code>items()</code> on this object can result in an instance of <code><a
|
||||
href="list.html#list-spec">boost::python::list</a></code> which actually
|
||||
holds a Python tuple. Subsequent attempts to use list methods (e.g.
|
||||
<code>append</code>, or any other mutating operation) on this object will
|
||||
raise the same exception that would occur if you tried to do it from
|
||||
Python.
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
124
doc/v2/ResultConverter.html
Normal file
@@ -0,0 +1,124 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../../../../boost.css">
|
||||
<title>Boost.Python - ResultConverter Concept</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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">ResultConverter Concept</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
<dt><a href="#concept-requirements">Concept Requirements</a></dt>
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#ResultConverter-concept">ResultConverter Concept</a></dt>
|
||||
<dt><a href="#ResultConverterGenerator-concept">ResultConverterGenerator Concept</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p>A ResultConverter for a type <code>T</code> is a type whose
|
||||
instances can be used to convert C++ return values of type
|
||||
<code>T</code> <code>to_python</code>. A ResultConverterGenerator is
|
||||
an MPL unary metafunction class which, given the return type of a C++
|
||||
function, returns a ResultConverter for that type. ResultConverters in
|
||||
Boost.Python generally inspect library's registry of converters to
|
||||
find a suitable converter, but converters which don't use the registry
|
||||
are also possible.
|
||||
|
||||
<h2><a name="concept-requirements"></a>Concept Requirements</h2>
|
||||
<h3><a name="ResultConverter-concept"></a>ResultConverter Concept</h3>
|
||||
|
||||
<p>In the table below, <code><b>C</b></code> denotes a ResultConverter
|
||||
type for a type <b><code>R</code></b> , <code><b>c</b></code> denotes
|
||||
an object of type <code><b>C</b></code> , and <code><b>r</b></code>
|
||||
denotes an object of type <code><b>R</b></code>.
|
||||
|
||||
<table summary="ResultConverter expressions" border="1" cellpadding="5">
|
||||
|
||||
<tr>
|
||||
<td><b>Expression</b></td>
|
||||
<td><b>Type</b></td>
|
||||
<td><b>Semantics</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>C c;</code></td>
|
||||
<td>
|
||||
<td>Constructs a <code>C</code> object.
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>c.convertible()</code></td>
|
||||
<td>convertible to <code>bool</code></td>
|
||||
<td><code>false</code> iff no conversion from any <code>R</code> value
|
||||
to a Python object is possible.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>c(r)</code></td>
|
||||
<td>convertible to <code>PyObject*</code></td>
|
||||
<td>A pointer to a Python object corresponding to <code>r</code>,
|
||||
or <code>0</code> iff <code>r</code> could not be converted
|
||||
<code>to_python</code>, in which case <a
|
||||
href="http://www.python.org/doc/current/api/exceptionHandling.html#l2h-71">PyErr_Occurred</a>
|
||||
should return non-zero.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><code>c.get_pytype()</code></td>
|
||||
<td><code>PyTypeObject const*</code></td>
|
||||
<td>A pointer to a Python Type object corresponding to result of the conversion,
|
||||
or <code>0</code>. Used for documentation generation. If <code>0</code> is returned
|
||||
the generated type in the documentation will be <b>object</b> .</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3><a name="ResultConverterGenerator-concept"></a>ResultConverterGenerator Concept</h3>
|
||||
<p>In the table below, <code><b>G</b></code> denotes a
|
||||
ResultConverterGenerator type and <code><b>R</b></code> denotes a possible
|
||||
C++ function return type.
|
||||
|
||||
<table summary="ResultConverterGenerator expressions" border="1" cellpadding="5">
|
||||
<tr>
|
||||
<td><b>Expression</b></td>
|
||||
<td><b>Requirements</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><code>G::apply<R>::type</code></td>
|
||||
<td>A ResultConverter type for <code>R</code>.</td>
|
||||
</table>
|
||||
|
||||
<hr>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
09 May, 2002 <!--Luann's birthday! -->
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. </i>
|
||||
|
||||
<p>Permission to copy, use, modify, sell
|
||||
and distribute this software is granted provided this copyright notice appears
|
||||
in all copies. This software is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.
|
||||
</body>
|
||||
</html>
|
||||
135
doc/v2/acknowledgments.html
Normal file
@@ -0,0 +1,135 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - Acknowledgments</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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Acknowledgments</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<p><a href="http://www.boost.org/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 <a href=
|
||||
"../tutorial/index.html">tutorial documentation</a>.</p>
|
||||
|
||||
<p><a href="http://www.boost.org/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 <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="http://www.boost.org/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="http://www.boost.org/people/paul_mensonides.htm">Paul Mensonides</a>,
|
||||
building on the work <a href="http://www.boost.org/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> ("Pie-Steh")
|
||||
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
|
||||
HTML templates for this documentation. Dave Hawkes contributed
|
||||
inspiration for the use of the <code><a href=
|
||||
"scope.html#scope-spec">scope</a></code> class to simplify module
|
||||
definition syntax. Pearu Pearson wrote some of the test cases that are in
|
||||
the current test suite.</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
|
||||
Crystallography Initiative</a> at Lawrence Berkeley National
|
||||
Laboratories.</p>
|
||||
|
||||
<p><a href="http://kogs-www.informatik.uni-hamburg.de/~koethe/">Ullrich
|
||||
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
|
||||
release as a Boost library.</p>
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
26 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
199
doc/v2/args.html
Normal file
@@ -0,0 +1,199 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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 - <boost/python/args.hpp></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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/args.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#keyword-expression"><i>keyword-expressions</i></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">
|
||||
<dt><code><a href=
|
||||
"#args-spec">args</a>(</code>...<code>)</code></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#examples">Example(s)</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p>Supplies a family of overloaded functions for specifying argument
|
||||
keywords for wrapped C++ functions.</p>
|
||||
|
||||
<h2><a name="keyword-expression"></a><i>keyword-expressions</i></h2>
|
||||
|
||||
<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. The <b>keyword-expression</b>
|
||||
may contain default values for some or all of the keywords it holds</p>
|
||||
|
||||
<h2><a name="classes"></a>Classes</h2>
|
||||
|
||||
<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>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
struct arg
|
||||
{
|
||||
template <class T>
|
||||
arg &perator = (T const &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> The argument must be a <a href=
|
||||
"definitions.html#ntbs">ntbs</a>.</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 <class T> arg &operator = (T const &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 &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>
|
||||
<pre>
|
||||
#include <boost/python/def.hpp>
|
||||
using namespace boost::python;
|
||||
|
||||
int f(double x, double y, double z=0.0, double w=1.0);
|
||||
|
||||
BOOST_PYTHON_MODULE(xxx)
|
||||
{
|
||||
def("f", f
|
||||
, ( arg("x"), "y", arg("z")=0.0, arg("w")=1.0 )
|
||||
);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Revised 01 August, 2003</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002-2003.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
85
doc/v2/call.html
Normal file
@@ -0,0 +1,85 @@
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
<title>Boost.Python - <call.hpp></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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">Header <call.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<h2>Contents</h2>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
<dt><a href="#functions">Functions</a></dt>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#call-spec">call</a></dt>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#examples">Example(s)</a></dt>
|
||||
|
||||
</dl>
|
||||
<hr>
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
<p>
|
||||
<code><boost/python/call.hpp></code> defines the <a
|
||||
href="#call-spec"><code>call</code></a> family of overloaded function
|
||||
templates, used to invoke Python callable objects from C++.
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
<pre>
|
||||
<a name="call-spec">template <class R, class A1, class A2, ... class A<i>n</i>></a>
|
||||
R call(PyObject* callable, A1 const&, A2 const&, ... A<i>n</i> const&)
|
||||
</pre>
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>R</code> is a pointer type, reference
|
||||
type, or a complete type with an accessible copy constructor</dt>
|
||||
|
||||
<dt><b>Effects:</b> Invokes <code>callable(a1, a2, ...a<i>n</i>)</code> in
|
||||
Python, where <code>a1</code>...<code>a<i>n</i></code> are the arguments to
|
||||
<code>call()</code>, converted to Python objects.
|
||||
<dt><b>Returns:</b> The result of the Python call, converted to the C++ type <code>R</code>.</dt>
|
||||
|
||||
</dt>
|
||||
<dt><b>Rationale:</b> For a complete semantic description and
|
||||
rationale, see <a href="callbacks.html">this page</a>.
|
||||
</dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example(s)</h2>
|
||||
|
||||
The following C++ function applies a Python callable object to its two
|
||||
arguments and returns the result. If a Python exception is raised or
|
||||
the result can't be converted to a <code>double</code>, an exception
|
||||
is thrown.
|
||||
|
||||
<pre>
|
||||
double apply2(PyObject* func, double x, double y)
|
||||
{
|
||||
return boost::python::call<double>(func, x, y);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
9 May, 2002 <!-- Luann's birthday! -->
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. </i></p>
|
||||
</body>
|
||||
</html>
|
||||
161
doc/v2/call_method.html
Normal file
@@ -0,0 +1,161 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - <call_method.hpp></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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header <call_method.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#functions">Functions</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#call_method-spec">call_method</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#examples">Example(s)</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p><code><boost/python/call_method.hpp></code> defines the <a href=
|
||||
"#call_method-spec"><code>call_method</code></a> family of overloaded
|
||||
function templates, used to invoke callable attributes of Python objects
|
||||
from C++.</p>
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
<pre>
|
||||
<a name=
|
||||
"call_method-spec">template <class R, class A1, class A2, ... class A<i>n</i>></a>
|
||||
R call_method(PyObject* self, char const* method, A1 const&, A2 const&, ... A<i>n</i> const&)
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>R</code> is a pointer type, reference type,
|
||||
or a complete type with an accessible copy constructor</dt>
|
||||
|
||||
<dt><b>Effects:</b> Invokes
|
||||
<code>self.<i>method</i>(a1, a2, ...a<i>n</i>)</code> in
|
||||
Python, where <code>a1</code>...<code>a<i>n</i></code> are the
|
||||
arguments to <code>call_method()</code>, converted to Python objects.
|
||||
For a complete semantic description, see <a href="callbacks.html">this
|
||||
page</a>.</dt>
|
||||
|
||||
<dt><b>Returns:</b> The result of the Python call, converted to the C++
|
||||
type <code>R</code>.</dt>
|
||||
|
||||
<dt><b>Rationale:</b> <code>call_method</code> is critical to
|
||||
implementing C++ virtual functions which are overridable in Python, as
|
||||
shown by the example below.</dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example(s)</h2>
|
||||
The following C++ illustrates the use of <code>call_method</code> in
|
||||
wrapping a class with a virtual function that can be overridden in
|
||||
Python:
|
||||
|
||||
<h3>C++ Module Definition</h3>
|
||||
<pre>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <cstring>
|
||||
|
||||
// class to be wrapped
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
virtual char const* class_name() const { return "Base"; }
|
||||
virtual ~Base();
|
||||
};
|
||||
|
||||
bool is_base(Base* b)
|
||||
{
|
||||
return !std::strcmp(b->class_name(), "Base");
|
||||
}
|
||||
|
||||
// Wrapper code begins here
|
||||
using namespace boost::python;
|
||||
|
||||
// Callback class
|
||||
class Base_callback : public Base
|
||||
{
|
||||
public:
|
||||
Base_callback(PyObject* self) : m_self(self) {}
|
||||
|
||||
char const* class_name() const { return <b>call_method</b><char const*>(m_self, "class_name"); }
|
||||
char const* Base_name() const { return Base::class_name(); }
|
||||
private:
|
||||
PyObject* const m_self;
|
||||
};
|
||||
|
||||
using namespace boost::python;
|
||||
BOOST_PYTHON_MODULE(my_module)
|
||||
{
|
||||
def("is_base", is_base);
|
||||
|
||||
class_<Base,Base_callback, noncopyable>("Base")
|
||||
.def("class_name", &Base_callback::Base_name)
|
||||
;
|
||||
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>Python Code</h3>
|
||||
<pre>
|
||||
>>> from my_module import *
|
||||
>>> class Derived(Base):
|
||||
... def __init__(self):
|
||||
... Base.__init__(self)
|
||||
... def class_name(self):
|
||||
... return self.__class__.__name__
|
||||
...
|
||||
>>> is_base(Base()) # calls the class_name() method from C++
|
||||
1
|
||||
>>> is_base(Derived())
|
||||
0
|
||||
</pre>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
254
doc/v2/callbacks.html
Normal file
@@ -0,0 +1,254 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - Calling Python Functions and Methods</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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Calling Python Functions and Methods</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#argument_handling">Argument Handling</a></dt>
|
||||
|
||||
<dt><a href="#result_handling">Result Handling</a></dt>
|
||||
|
||||
<dt><a href="#result_handling">Rationale</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction">Introduction</a></h2>
|
||||
The simplest way to call a Python function from C++, given an <code><a
|
||||
href="object.html#object-spec">object</a></code> instance <code>f</code>
|
||||
holding the function, is simply to invoke its function call operator.
|
||||
<pre>
|
||||
f("tea", 4, 2) // In Python: f('tea', 4, 2)
|
||||
</pre>
|
||||
And of course, a method of an <code><a href=
|
||||
"object.html#object-spec">object</a></code> instance <code>x</code> can
|
||||
be invoked by using the function-call operator of the corresponding
|
||||
attribute:
|
||||
<pre>
|
||||
x.attr("tea")(4, 2); // In Python: x.tea(4, 2)
|
||||
</pre>
|
||||
|
||||
<p>If you don't have an <code>object</code> instance, Boost.Python
|
||||
provides two families of function templates, <code><a href=
|
||||
"call.html#call-spec">call</a></code> and <code><a href=
|
||||
"call_method.html#call_method-spec">call_method</a></code>, for invoking
|
||||
Python functions and methods respectively on <code>PyObject*</code>s. The
|
||||
interface for calling a Python function object (or any Python callable
|
||||
object) looks like:</p>
|
||||
<pre>
|
||||
call<ResultType>(callable_object, a1, a2... a<i>N</i>);
|
||||
</pre>
|
||||
Calling a method of a Python object is similarly easy:
|
||||
<pre>
|
||||
call_method<ResultType>(self_object, "<i>method-name</i>", a1, a2... a<i>N</i>);
|
||||
</pre>
|
||||
This comparitively low-level interface is the one you'll use when
|
||||
implementing C++ virtual functions that can be overridden in Python.
|
||||
|
||||
<h2><a name="argument_handling">Argument Handling</a></h2>
|
||||
|
||||
<p>Arguments are converted to Python according to their type. By default,
|
||||
the arguments <code>a1</code>...<code>a<i>N</i></code> are copied into
|
||||
new Python objects, but this behavior can be overridden by the use of
|
||||
<code><a href="ptr.html#ptr-spec">ptr()</a></code> and <a href=
|
||||
"../../../bind/ref.html">ref()</a>:</p>
|
||||
<pre>
|
||||
class X : boost::noncopyable
|
||||
{
|
||||
...
|
||||
};
|
||||
|
||||
void apply(PyObject* callable, X& x)
|
||||
{
|
||||
// Invoke callable, passing a Python object which holds a reference to x
|
||||
boost::python::call<void>(callable, boost::ref(x));
|
||||
}
|
||||
</pre>
|
||||
In the table below, <code><b>x</b></code> denotes the actual argument
|
||||
object and <code><b>cv</b></code> denotes an optional
|
||||
<i>cv-qualification</i>: "<code>const</code>", "<code>volatile</code>",
|
||||
or "<code>const volatile</code>".
|
||||
|
||||
<table border="1" summary="class_ template parameters">
|
||||
<tr>
|
||||
<th>Argument Type</th>
|
||||
|
||||
<th>Behavior</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>T cv&</code><br>
|
||||
<code>T cv</code></td>
|
||||
|
||||
<td>The Python argument is created by the same means used for the
|
||||
return value of a wrapped C++ function returning <code>T</code>. When
|
||||
<code>T</code> is a class type, that normally means <code>*x</code>
|
||||
is copy-constructed into the new Python object.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>T*</code></td>
|
||||
|
||||
<td>If <code>x == 0</code>, the Python argument will be
|
||||
<code><a href=
|
||||
"http://www.python.org/doc/current/lib/bltin-null-object.html">None</a></code>.
|
||||
Otherwise, the Python argument is created by the same means used for
|
||||
the return value of a wrapped C++ function returning <code>T</code>.
|
||||
When <code>T</code> is a class type, that normally means
|
||||
<code>*x</code> is copy-constructed into the new Python object.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code><a href=
|
||||
"../../../bind/ref.html">boost::reference_wrapper</a><T></code></td>
|
||||
|
||||
<td>The Python argument contains a pointer to, rather than a copy of,
|
||||
<code>x.get()</code>. Note: failure to ensure that no Python code
|
||||
holds a reference to the resulting object beyond the lifetime of
|
||||
<code>*x.get()</code> <b>may result in a crash!</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code><a href=
|
||||
"ptr.html#pointer_wrapper-spec">pointer_wrapper</a><T></code></td>
|
||||
|
||||
<td>If <code>x.get() == 0</code>, the Python argument will
|
||||
be <code><a href=
|
||||
"http://www.python.org/doc/current/lib/bltin-null-object.html">None</a></code>.
|
||||
Otherwise, the Python argument contains a pointer to, rather than a
|
||||
copy of, <code>*x.get()</code>. Note: failure to ensure that no
|
||||
Python code holds a reference to the resulting object beyond the
|
||||
lifetime of <code>*x.get()</code> <b>may result in a crash!</b></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="result_handling">Result Handling</a></h2>
|
||||
In general, <code>call<ResultType>()</code> and
|
||||
<code>call_method<ResultType>()</code> return
|
||||
<code>ResultType</code> by exploiting all lvalue and rvalue
|
||||
<code>from_python</code> converters registered for ResultType and
|
||||
returning a copy of the result. However, when <code>ResultType</code> is
|
||||
a pointer or reference type, Boost.Python searches only for lvalue
|
||||
converters. To prevent dangling pointers and references, an exception
|
||||
will be thrown if the Python result object has only a single reference
|
||||
count.
|
||||
|
||||
<h2><a name="rationale">Rationale</a></h2>
|
||||
In general, to get Python arguments corresponding to
|
||||
<code>a1</code>...<code>a<i>N</i></code>, a new Python object must be
|
||||
created for each one; should the C++ object be copied into that Python
|
||||
object, or should the Python object simply hold a reference/pointer to
|
||||
the C++ object? In general, the latter approach is unsafe, since the
|
||||
called function may store a reference to the Python object somewhere. If
|
||||
the Python object is used after the C++ object is destroyed, we'll crash
|
||||
Python.
|
||||
|
||||
<p>In keeping with the philosophy that users on the Python side shouldn't
|
||||
have to worry about crashing the interpreter, the default behavior is to
|
||||
copy the C++ object, and to allow a non-copying behavior only if the user
|
||||
writes <code><a href="../../../bind/ref.html">boost::ref</a>(a1)</code>
|
||||
instead of a1 directly. At least this way, the user doesn't get dangerous
|
||||
behavior "by accident". It's also worth noting that the non-copying
|
||||
("by-reference") behavior is in general only available for class types,
|
||||
and will fail at runtime with a Python exception if used otherwise[<a
|
||||
href="#1">1</a>].</p>
|
||||
|
||||
<p>However, pointer types present a problem: one approach is to refuse to
|
||||
compile if any aN has pointer type: after all, a user can always pass
|
||||
<code>*aN</code> to pass "by-value" or <code>ref(*aN)</code> to indicate
|
||||
a pass-by-reference behavior. However, this creates a problem for the
|
||||
expected null pointer to <code>None</code> conversion: it's illegal to
|
||||
dereference a null pointer value.</p>
|
||||
|
||||
<p>The compromise I've settled on is this:</p>
|
||||
|
||||
<ol>
|
||||
<li>The default behavior is pass-by-value. If you pass a non-null
|
||||
pointer, the pointee is copied into a new Python object; otherwise the
|
||||
corresponding Python argument will be None.</li>
|
||||
|
||||
<li>if you want by-reference behavior, use <code>ptr(aN)</code> if
|
||||
<code>aN</code> is a pointer and <code>ref(aN)</code> otherwise. If a
|
||||
null pointer is passed to <code>ptr(aN)</code>, the corresponding
|
||||
Python argument will be <code>None</code>.</li>
|
||||
</ol>
|
||||
|
||||
<p>As for results, we have a similar problem: if <code>ResultType</code>
|
||||
is allowed to be a pointer or reference type, the lifetime of the object
|
||||
it refers to is probably being managed by a Python object. When that
|
||||
Python object is destroyed, our pointer dangles. The problem is
|
||||
particularly bad when the <code>ResultType</code> is char const* - the
|
||||
corresponding Python String object is typically uniquely-referenced,
|
||||
meaning that the pointer dangles as soon as <code>call<char
|
||||
const*>(...)</code> returns.</p>
|
||||
|
||||
<p>The old Boost.Python v1 deals with this issue by refusing to compile
|
||||
any uses of <code>call<char const*>()</code>, but this goes both
|
||||
too far and not far enough. It goes too far because there are cases where
|
||||
the owning Python string object survives beyond the call (just for
|
||||
instance, when it's the name of a Python class), and it goes not far
|
||||
enough because we might just as well have the same problem with a
|
||||
returned pointer or reference of any other type.</p>
|
||||
|
||||
<p>In Boost.Python v2 this is dealt with by:</p>
|
||||
|
||||
<ol>
|
||||
<li>lifting the compile-time restriction on const char* callback
|
||||
returns</li>
|
||||
|
||||
<li>detecting the case when the reference count on the result Python
|
||||
object is 1 and throwing an exception inside of
|
||||
<code>call<U>(...)</code> when <code>U</code> is a pointer or
|
||||
reference type.</li>
|
||||
</ol>
|
||||
This should be acceptably safe because users have to explicitly specify a
|
||||
pointer/reference for <code>U</code> in <code>call<U></code>, and
|
||||
they will be protected against dangles at runtime, at least long enough
|
||||
to get out of the <code>call<U>(...)</code> invocation.
|
||||
<hr>
|
||||
<a name="1">[1]</a> It would be possible to make it fail at compile-time
|
||||
for non-class types such as int and char, but I'm not sure it's a good
|
||||
idea to impose this restriction yet.
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
92
doc/v2/callbacks.txt
Normal file
@@ -0,0 +1,92 @@
|
||||
.. Copyright David Abrahams 2006. Distributed under the Boost
|
||||
.. Software License, Version 1.0. (See accompanying
|
||||
.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
Here's the plan:
|
||||
|
||||
I aim to provide an interface similar to that of Boost.Python v1's
|
||||
callback<>::call(...) for dealing with callbacks. The interface will
|
||||
look like:
|
||||
|
||||
returning<ResultType>::call("method_name", self_object, a1, a2...);
|
||||
|
||||
or
|
||||
|
||||
returning<ResultType>::call(callable_object, a1, a2...);
|
||||
|
||||
ARGUMENT HANDLING
|
||||
|
||||
There is an issue concerning how to make Python objects from the
|
||||
arguments a1...aN. A new Python object must be created; should the C++
|
||||
object be copied into that Python object, or should the Python object
|
||||
simply hold a reference/pointer to the C++ object? In general, the
|
||||
latter approach is unsafe, since the called function may store a
|
||||
reference to the Python object somewhere. If the Python object is used
|
||||
after the C++ object is destroyed, we'll crash Python.
|
||||
|
||||
I plan to make the copying behavior the default, and to allow a
|
||||
non-copying behavior if the user writes boost::ref(a1) instead of a1
|
||||
directly. At least this way, the user doesn't get dangerous behavior "by
|
||||
accident". It's also worth noting that the non-copying ("by-reference")
|
||||
behavior is in general only available for class types, and will fail at
|
||||
runtime with a Python exception if used otherwise**
|
||||
|
||||
However, pointer types present a problem: My first thought is to refuse
|
||||
to compile if any aN has pointer type: after all, a user can always pass
|
||||
*aN to pass "by-value" or ref(*aN) to indicate a pass-by-reference
|
||||
behavior. However, this creates a problem for the expected NULL pointer
|
||||
=> None conversion: it's illegal to dereference a null pointer value.
|
||||
|
||||
We could use another construct, say "ptr(aN)", to deal with null
|
||||
pointers, but then what does it mean? We know what it does when aN is
|
||||
NULL, but it might either have by-value or by-reference behavior when aN
|
||||
is non-null.
|
||||
|
||||
The compromise I've settled on is this:
|
||||
|
||||
1. The default behavior is pass-by-value. If you pass a non-null
|
||||
pointer, the pointee is copied into a new Python object; otherwise
|
||||
the corresponding Python argument will be None.
|
||||
|
||||
2. if you want by-reference behavior, use ptr(aN) if aN is a pointer
|
||||
and ref(aN) otherwise. If a null pointer is passed to ptr(aN), the
|
||||
corresponding Python argument will be None.
|
||||
|
||||
RESULT HANDLING
|
||||
|
||||
As for results, we have a similar problem: if ResultType is allowed to
|
||||
be a pointer or reference type, the lifetime of the object it refers to
|
||||
is probably being managed by a Python object. When that Python object is
|
||||
destroyed, our pointer dangles. The problem is particularly bad when the
|
||||
ResultType is char const* - the corresponding Python String object is
|
||||
typically uniquely-referenced, meaning that the pointer dangles as soon
|
||||
as returning<char const*>::call() returns.
|
||||
|
||||
Boost.Python v1 deals with this issue by refusing to compile any uses of
|
||||
callback<char const*>::call(), but IMO this goes both too far and not
|
||||
far enough. It goes too far because there are cases where the owning
|
||||
String object survives beyond the call (just for instance when it's the
|
||||
name of a Python class), and it goes not far enough because we might
|
||||
just as well have the same problem with any returned pointer or
|
||||
reference.
|
||||
|
||||
I propose to address this in Boost.Python v2 by
|
||||
|
||||
1. lifting the compile-time restriction on const
|
||||
char* callback returns
|
||||
|
||||
2. detecting the case when the reference count on the
|
||||
result Python object is 1 and throwing an exception
|
||||
inside of returning<U>::call() when U is a pointer or
|
||||
reference type.
|
||||
|
||||
I think this is acceptably safe because users have to explicitly specify
|
||||
a pointer/reference for U in returning<U>, and they will be protected
|
||||
against dangles at runtime, at least long enough to get out of the
|
||||
returning<U>::call() invocation.
|
||||
|
||||
-Dave
|
||||
|
||||
**It would be possible to make it fail at compile-time for non-class
|
||||
types such as int and char, but I'm not sure it's a good idea to impose
|
||||
this restriction yet.
|
||||
790
doc/v2/class.html
Normal file
@@ -0,0 +1,790 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Cygwin (vers 1st September 2004), see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-latin-1-dos">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - <boost/python/class.hpp>,
|
||||
<boost/python/class_fwd.hpp></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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Headers <boost/python/class.hpp>,
|
||||
<boost/python/class_fwd.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#class_-spec">Class template
|
||||
<code>class_</code></a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#class_-spec-synopsis">Class <code>class_</code>
|
||||
synopsis</a></dt>
|
||||
|
||||
<dt><a href="#class_-spec-ctors">Class <code>class_</code>
|
||||
constructors</a></dt>
|
||||
|
||||
<dt><a href="#class_-spec-modifiers">Class <code>class_</code>
|
||||
modifier functions</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#bases-spec">Class template <code>bases</code></a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#bases-spec-synopsis">Class template
|
||||
<code>bases</code> synopsis</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#examples">Example(s)</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction" id="introduction"></a>Introduction</h2>
|
||||
|
||||
<p><code><boost/python/class.hpp></code> defines the interface
|
||||
through which users expose their C++ classes to Python. It declares the
|
||||
<code>class_</code> class template, which is parameterized on the class
|
||||
type being exposed. It also exposes the <code>init</code>,
|
||||
<code>optional</code> and <code>bases</code> utility class templates, which
|
||||
are used in conjunction with <code>class_</code>.</p>
|
||||
|
||||
<p><code><boost/python/class_fwd.hpp></code> contains a forward
|
||||
declaration of the <code>class_</code> class template.</p>
|
||||
|
||||
<h2><a name="classes" id="classes"></a>Classes</h2>
|
||||
|
||||
<h3><a name="class_-spec" id="class_-spec"></a>Class template
|
||||
<code>class_<T, <font color="#007F00">Bases, HeldType,
|
||||
NonCopyable</font>></code></h3>
|
||||
|
||||
<p>Creates a Python class associated with the C++ type passed as its first
|
||||
parameter. Although it has four template parameters, only the first one is
|
||||
required. The three optional arguments can actually be supplied
|
||||
<font color="#007F00"><b>in any order</b></font>; Boost.Python determines
|
||||
the role of the argument from its type.<br>
|
||||
<br></p>
|
||||
|
||||
<table border="1" summary="class_ template parameters">
|
||||
<tr>
|
||||
<th>Template Parameter</th>
|
||||
|
||||
<th>Requirements</th>
|
||||
|
||||
<th>Semantics</th>
|
||||
|
||||
<th>Default</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>T</code></td>
|
||||
|
||||
<td>A class type.</td>
|
||||
|
||||
<td>The class being wrapped</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code><font color="#007F00">Bases</font></code></td>
|
||||
|
||||
<td>A specialization of <a href=
|
||||
"#bases-spec"><code>bases<</code>...<code>></code></a> which
|
||||
specifies previously-exposed C++ base classes of <code>T</code><a href=
|
||||
"#footnote_1">[1]</a>.</td>
|
||||
|
||||
<td>Registers <code>from_python</code> conversions from wrapped
|
||||
<code>T</code> instances to each of its exposed direct and indirect
|
||||
bases. For each polymorphic base <code>B</code>, registers conversions
|
||||
from indirectly-held wrapped <code>B</code> instances to
|
||||
<code>T</code>.</td>
|
||||
|
||||
<td><code><a href="#bases-spec">bases<></a></code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code><font color="#007F00">HeldType</font></code></td>
|
||||
|
||||
<td>Must be <code>T</code>, a class derived from <code>T</code>, or a
|
||||
<a href="Dereferenceable.html">Dereferenceable</a> type for which
|
||||
<code><a href=
|
||||
"pointee.html#pointee-spec">pointee</a><HeldType>::type</code> is
|
||||
<code>T</code> or a class derived from <code>T</code>.</td>
|
||||
|
||||
<td>Specifies the type that is actually embedded in a Python object
|
||||
wrapping a <code>T</code> instance when <code>T</code>'s constructor is
|
||||
called or when a <code>T</code> or <code>T*</code> is converted to
|
||||
Python without the use of <a href=
|
||||
"http://www.boost.org/libs/python/doc/v2/callbacks.html#argument_handling">
|
||||
<code>ptr</code></a>, <a href=
|
||||
"http://www.boost.org/libs/python/doc/v2/callbacks.html#argument_handling">
|
||||
<code>ref</code></a>, or <a href="CallPolicies.html">Call Policies</a>
|
||||
such as <code><a href=
|
||||
"return_internal_reference.html">return_internal_reference</a></code>.
|
||||
More details <a href="#HeldType">below</a>.</td>
|
||||
|
||||
<td><code>T</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code><font color="#007F00">NonCopyable</font></code></td>
|
||||
|
||||
<td>If supplied, must be <a href=
|
||||
"../../../utility/utility.htm#Class_noncopyable">boost::noncopyable</a>.</td>
|
||||
|
||||
<td>Suppresses automatic registration of <code>to_python</code>
|
||||
conversions which copy <code>T</code> instances. Required when
|
||||
<code>T</code> has no publicly-accessible copy constructor.</td>
|
||||
|
||||
<td>An unspecified type other than
|
||||
<code>boost::noncopyable</code>.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h4><a name="HeldType" id="HeldType">HeldType Semantics</a></h4>
|
||||
|
||||
<ol>
|
||||
<li>If <code>HeldType</code> is derived from T, its exposed
|
||||
constructor(s) must accept an initial <code>PyObject*</code> argument
|
||||
which refers back to the Python object that contains the
|
||||
<code>HeldType</code> instance, as shown in <a href=
|
||||
"call_method.html#examples">this example</a>. This argument is not
|
||||
included in the <em><a href=
|
||||
"init.html#init-expressions">init-expression</a></em> passed to <a href=
|
||||
"#class_-spec-modifiers"><code>def(init_expr)</code></a>, below, nor is
|
||||
it passed explicitly by users when Python instances of <code>T</code> are
|
||||
created. This idiom allows C++ virtual functions which will be overridden
|
||||
in Python to access the Python object so the Python method can be
|
||||
invoked. Boost.Python automatically registers additional converters which
|
||||
allow wrapped instances of <code>T</code> to be passed to wrapped C++
|
||||
functions expecting <code>HeldType</code> arguments.</li>
|
||||
|
||||
<li>Because Boost.Python will always allow wrapped instances of
|
||||
<code>T</code> to be passed in place of <code>HeldType</code> arguments,
|
||||
specifying a smart pointer for <code>HeldType</code> allows users to pass
|
||||
Python <code>T</code> instances where a smart pointer-to-<code>T</code>
|
||||
is expected. Smart pointers such as <code>std::auto_ptr<></code> or
|
||||
<code><a href=
|
||||
"../../../smart_ptr/shared_ptr.htm">boost::shared_ptr<></a></code>
|
||||
which contain a nested type <code>element_type</code> designating the
|
||||
referent type are automatically supported; additional smart pointer types
|
||||
can be supported by specializing <a href=
|
||||
"pointee.html#pointee-spec">pointee<HeldType></a>.</li>
|
||||
|
||||
<li>As in case 1 above, when <code>HeldType</code> is a smart pointer to
|
||||
a class derived from <code>T</code>, the initial <code>PyObject*</code>
|
||||
argument must be supplied by all of <code>HeldType</code>'s exposed
|
||||
constructors.</li>
|
||||
|
||||
<li>Except in cases 1 and 3, users may optionally specify that T itself
|
||||
gets initialized with a similar initial <code>PyObject*</code> argument
|
||||
by specializing <a href=
|
||||
"has_back_reference.html#has_back_reference-spec">has_back_reference<T></a>.</li>
|
||||
</ol>
|
||||
|
||||
<h4><a name="class_-spec-synopsis" id="class_-spec-synopsis"></a>Class
|
||||
template <code>class_</code> synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template <class T
|
||||
<font color="#007F00"> , class Bases = bases<>
|
||||
, class HeldType = T
|
||||
, class NonCopyable = <i>unspecified</i>
|
||||
>
|
||||
</font> class class_ : public <a href="object.html#object-spec">object</a>
|
||||
{
|
||||
// Constructors with default __init__
|
||||
class_(char const* name);
|
||||
class_(char const* name, char const* docstring);
|
||||
|
||||
// Constructors, specifying non-default __init__
|
||||
template <class Init>
|
||||
class_(char const* name, Init);
|
||||
template <class Init>
|
||||
class_(char const* name, char const* docstring, Init);
|
||||
|
||||
// Exposing additional __init__ functions
|
||||
template <class Init>
|
||||
class_& def(Init);
|
||||
|
||||
// defining methods
|
||||
template <class F>
|
||||
class_& def(char const* name, F f);
|
||||
template <class Fn, class A1>
|
||||
class_& def(char const* name, Fn fn, A1 const&);
|
||||
template <class Fn, class A1, class A2>
|
||||
class_& def(char const* name, Fn fn, A1 const&, A2 const&);
|
||||
template <class Fn, class A1, class A2, class A3>
|
||||
class_& def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);
|
||||
|
||||
// declaring method as static
|
||||
class_& staticmethod(char const* name);
|
||||
|
||||
// exposing operators
|
||||
template <<i>unspecified</i>>
|
||||
class_& def(<a href=
|
||||
"operators.html#operator_-spec">detail::operator_</a><unspecified>);
|
||||
|
||||
// Raw attribute modification
|
||||
template <class U>
|
||||
class_& setattr(char const* name, U const&);
|
||||
|
||||
// exposing data members
|
||||
template <class D>
|
||||
class_& def_readonly(char const* name, D T::*pm);
|
||||
|
||||
template <class D>
|
||||
class_& def_readwrite(char const* name, D T::*pm);
|
||||
|
||||
// exposing static data members
|
||||
template <class D>
|
||||
class_& def_readonly(char const* name, D const& d);
|
||||
template <class D>
|
||||
class_& def_readwrite(char const* name, D& d);
|
||||
|
||||
// property creation
|
||||
template <class Get>
|
||||
void add_property(char const* name, Get const& fget, char const* doc=0);
|
||||
template <class Get, class Set>
|
||||
void add_property(
|
||||
char const* name, Get const& fget, Set const& fset, char const* doc=0);
|
||||
|
||||
template <class Get>
|
||||
void add_static_property(char const* name, Get const& fget);
|
||||
template <class Get, class Set>
|
||||
void add_static_property(char const* name, Get const& fget, Set const& fset);
|
||||
|
||||
// pickle support
|
||||
template <typename PickleSuite>
|
||||
self& def_pickle(PickleSuite const&);
|
||||
self& enable_pickling();
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="class_-spec-ctors" id="class_-spec-ctors"></a>Class template
|
||||
<code>class_</code> constructors</h4>
|
||||
<pre>
|
||||
class_(char const* name);
|
||||
class_(char const* name, char const* docstring);
|
||||
template <class Init>
|
||||
class_(char const* name, Init init_spec);
|
||||
template <class Init>
|
||||
class_(char const* name, char const* docstring, Init init_spec);
|
||||
</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>. If <code>docstring</code> is supplied, it must be an
|
||||
<a href="definitions.html#ntbs">ntbs</a>. If <code>init_spec</code> is
|
||||
supplied, it must be either the special enumeration constant
|
||||
<code>no_init</code> or an <a href=
|
||||
"init.html#init-expressions">init-expression</a> compatible with
|
||||
<code>T</code>.</dt>
|
||||
|
||||
<dt><b>Effects:</b> Constructs a <code>class_</code> object holding a
|
||||
Boost.Python extension class named <code>name</code>. The
|
||||
<code>name</code>d attribute of the <a href=
|
||||
"scope.html#introduction">current scope</a> is bound to the new extension
|
||||
class.</dt>
|
||||
|
||||
<dd>
|
||||
<ul>
|
||||
<li>If supplied, the value of <code>docstring</code> is bound to the
|
||||
<code>__doc__</code> attribute of the extension class.</li>
|
||||
|
||||
<li>If <code>init_spec</code> is <code>no_init</code>, a special
|
||||
<code>__init__</code> function is generated which always raises a
|
||||
Python exception. Otherwise, <code>this->def(init_spec)</code> is
|
||||
called.</li>
|
||||
|
||||
<li>If <code>init_spec</code> is not supplied,
|
||||
<code>this->def(init<>())</code> is called.</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt><b>Rationale:</b>Allowing the user to specify constructor arguments
|
||||
in the <code>class_<></code> constructor helps her to avoid the
|
||||
common run-time errors which result from invoking wrapped member
|
||||
functions without having exposed an <code>__init__</code> function which
|
||||
creates the requisite <code>T</code> instance. Types which are not
|
||||
default-constructible will cause a compile-time error unless
|
||||
<code>Init</code> is supplied. The user must always supply
|
||||
<code>name</code> as there is currently no portable method to derive the
|
||||
text of the class name from its type.</dt>
|
||||
</dl>
|
||||
|
||||
<h4><a name="class_-spec-modifiers" id="class_-spec-modifiers"></a>Class
|
||||
template <code>class_</code> modifier functions</h4>
|
||||
<pre>
|
||||
template <class Init>
|
||||
class_& def(Init init_expr);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>init_expr</code> is the result of an <a href=
|
||||
"init.html#init-expressions">init-expression</a> compatible with
|
||||
<code>T</code>.</dt>
|
||||
|
||||
<dt><b>Effects:</b> For each <a href="init.html#init-expressions">valid
|
||||
prefix</a> <em>P</em> of <code>Init</code>, adds an
|
||||
<code>__init__(</code>...<code>)</code> function overload to the
|
||||
extension class accepting <em>P</em> as arguments. Each overload
|
||||
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> - <em>M</em> arguments of each
|
||||
overload.</dt>
|
||||
|
||||
<dt><b>Returns:</b> <code>*this</code></dt>
|
||||
|
||||
<dt><b>Rationale:</b> Allows users to easily expose a class' constructor
|
||||
to Python.</dt>
|
||||
</dl><br>
|
||||
<pre>
|
||||
template <class F>
|
||||
class_& def(char const* name, Fn fn);
|
||||
template <class Fn, class A1>
|
||||
class_& def(char const* name, Fn fn, A1 const& a1);
|
||||
template <class Fn, class A1, class A2>
|
||||
class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2);
|
||||
template <class Fn, class A1, class A2, class A3>
|
||||
class_& def(char const* name, Fn fn, A1 const& a1, A2 const& a2, A3 const& a3);
|
||||
</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>
|
||||
|
||||
<dd>
|
||||
<ul>
|
||||
<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>.
|
||||
|
||||
<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>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>
|
||||
contains <em>N</em> types and <code>a1</code> holds <em>M</em>
|
||||
keywords, an initial sequence of the keywords are used for all
|
||||
but the first <em>N</em> - <em>M</em> arguments of each
|
||||
overload.<br></dt>
|
||||
</dl>
|
||||
</li>
|
||||
|
||||
<li>Otherwise, a single method overload is built around fn, which
|
||||
must not be null:
|
||||
|
||||
<ul>
|
||||
<li>If fn is a function pointer, its first argument must be of
|
||||
the form <code>U</code>, <code>U <em>cv</em>&</code>, <code>U
|
||||
<em>cv</em>*</code>, or <code>U <em>cv</em>* const&</code>,
|
||||
where <code>T*</code> is convertible to <code>U*</code>, and
|
||||
<code>a1</code>-<code>a3</code>, if supplied, may be selected in
|
||||
any order from the table below.</li>
|
||||
|
||||
<li>Otherwise, if fn is a member function pointer, its target
|
||||
must be <code>T</code> or one of its public base classes, and
|
||||
<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. If an earlier overload
|
||||
supplied a docstring, two newline characters and the new
|
||||
docstring are appended to it.</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>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt><b>Returns:</b> <code>*this</code></dt>
|
||||
</dl>
|
||||
<pre>
|
||||
class_& 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 <<i>unspecified</i>>
|
||||
class_& def(<a href=
|
||||
"operators.html#operator_-spec">detail::operator_</a><unspecified>);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Effects:</b> Adds a Python <a href=
|
||||
"http://www.python.org/doc/ref/specialnames.html">special method</a> as
|
||||
described <a href="operators.html">here</a>.</dt>
|
||||
|
||||
<dt><b>Returns:</b> <code>*this</code></dt>
|
||||
</dl>
|
||||
<pre>
|
||||
template <class U>
|
||||
class_& setattr(char const* name, U const& u);
|
||||
</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> Converts u to Python and adds it to the attribute
|
||||
dictionary of the extension class:</dt>
|
||||
|
||||
<dd>
|
||||
<blockquote>
|
||||
<code><a href=
|
||||
"http://www.python.org/doc/current/api/object.html#l2h-166">PyObject_SetAttrString</a>(this->ptr(),
|
||||
name, <a href=
|
||||
"object.html#object-spec-ctors">object</a>(u).ptr());</code>
|
||||
</blockquote>
|
||||
</dd>
|
||||
|
||||
<dt><b>Returns:</b> <code>*this</code></dt>
|
||||
</dl><br>
|
||||
<pre>
|
||||
template <class Get>
|
||||
void add_property(char const* name, Get const& fget, char const* doc=0);
|
||||
template <class Get, class Set>
|
||||
void add_property(
|
||||
char const* name, Get const& fget, Set const& fset, char const* doc=0);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Requires:</b> <code>name</code> is an <a href=
|
||||
"definitions.html#ntbs">ntbs</a> which conform 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 new Python <a href=
|
||||
"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 second form) with an (optional) docstring <code>doc</code> to its
|
||||
constructor, then adds that property to the Python class object under
|
||||
construction with the given attribute <code>name</code>.</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 attribute access syntax.</dt>
|
||||
</dl><br>
|
||||
<pre>
|
||||
template <class Get>
|
||||
void add_static_property(char const* name, Get const& fget);
|
||||
template <class Get, class Set>
|
||||
void add_static_property(char const* name, Get const& fget, Set const& 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 <class D>
|
||||
class_& def_readonly(char const* name, D T::*pm, char const* doc=0);
|
||||
template <class D>
|
||||
class_& def_readonly(char const* name, D const& d);
|
||||
</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>. <code>doc</code> is also an ntbs.</dt>
|
||||
|
||||
<dt><b>Effects:</b></dt>
|
||||
|
||||
<dd>
|
||||
<pre>
|
||||
this->add_property(name, <a href=
|
||||
"data_members.html#make_getter-spec">make_getter</a>(pm), doc);
|
||||
</pre>and
|
||||
<pre>
|
||||
this->add_static_property(name, <a href=
|
||||
"data_members.html#make_getter-spec">make_getter</a>(d));
|
||||
</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
|
||||
or free variable such that it can be inspected from Python with a natural
|
||||
syntax.</dt>
|
||||
</dl>
|
||||
<pre>
|
||||
template <class D>
|
||||
class_& def_readwrite(char const* name, D T::*pm, char const* doc=0);
|
||||
template <class D>
|
||||
class_& def_readwrite(char const* name, D& d);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Effects:</b></dt>
|
||||
|
||||
<dd>
|
||||
<pre>
|
||||
this->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), doc);
|
||||
</pre>and
|
||||
<pre>
|
||||
this->add_static_property(name, <a href=
|
||||
"data_members.html#make_getter-spec">make_getter</a>(d), <a href=
|
||||
"data_members.html#make_setter-spec">make_setter</a>(d));
|
||||
</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 or free
|
||||
variable member such that it can be inspected and set from Python with a
|
||||
natural syntax.</dt>
|
||||
</dl>
|
||||
<pre>
|
||||
template <typename PickleSuite>
|
||||
class_& def_pickle(PickleSuite const&);
|
||||
</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>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>
|
||||
|
||||
<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>
|
||||
</dl><br>
|
||||
<pre>
|
||||
class_& 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>
|
||||
|
||||
<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>
|
||||
|
||||
<h3><a name="bases-spec" id="bases-spec"></a>Class template
|
||||
<code>bases<T1, T2,</code>...<code>TN></code></h3>
|
||||
|
||||
<p>An <a href="../../../mpl/doc/refmanual/forward-sequence.html">MPL
|
||||
sequence</a> which can be used in
|
||||
<code>class_<</code>...<code>></code> instantiations indicate a list
|
||||
of base classes.</p>
|
||||
|
||||
<h4><a name="bases-spec-synopsis" id="bases-spec-synopsis"></a>Class
|
||||
template <code>bases</code> synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template <T1 = <i>unspecified</i>,...T<i>n</i> = <i>unspecified</i>>
|
||||
struct bases
|
||||
{};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h2><a name="examples" id="examples"></a>Example(s)</h2>
|
||||
|
||||
<p>Given a C++ class declaration:</p>
|
||||
<pre>
|
||||
class Foo : public Bar, public Baz
|
||||
{
|
||||
public:
|
||||
Foo(int x, char const* y);
|
||||
Foo(double);
|
||||
|
||||
std::string const& name() { return m_name; }
|
||||
void name(char const*);
|
||||
|
||||
double value; // public data
|
||||
private:
|
||||
...
|
||||
};
|
||||
</pre>A corresponding Boost.Python extension class can be created with:
|
||||
<pre>
|
||||
using namespace boost::python;
|
||||
|
||||
class_<Foo,bases<Bar,Baz> >("Foo",
|
||||
"This is Foo's docstring."
|
||||
"It describes our Foo extension class",
|
||||
|
||||
init<int,char const*>(args("x","y"), "__init__ docstring")
|
||||
)
|
||||
.def(init<double>())
|
||||
.def("get_name", &Foo::get_name, return_internal_reference<>())
|
||||
.def("set_name", &Foo::set_name)
|
||||
.def_readwrite("value", &Foo::value)
|
||||
;
|
||||
</pre>
|
||||
<hr>
|
||||
<a name="footnote_1" id="footnote_1">[1]</a> By "previously-exposed" we
|
||||
mean that the for each <code>B</code> in <code>bases</code>, an instance of
|
||||
<code>class_<B<font color="#007F00">, ...</font>></code> must have
|
||||
already been constructed.
|
||||
<pre>
|
||||
class_<Base>("Base");
|
||||
class_<Derived, bases<Base> >("Derived");
|
||||
</pre>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
1 November, 2005 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
217
doc/v2/configuration.html
Normal file
@@ -0,0 +1,217 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - Configuration</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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Configuration</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#app-defined">Application Defined Macros</a></dt>
|
||||
|
||||
<dt><a href="#lib-defined-impl">Library Defined Implementation
|
||||
Macros</a></dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p><b>Boost.Python</b> uses several configuration macros in <a href=
|
||||
"http://www.boost.org/libs/config/config.htm"><boost/config.hpp></a>,
|
||||
as well as configuration macros meant to be supplied by the application.
|
||||
These macros are documented here.</p>
|
||||
|
||||
<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++
|
||||
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></th>
|
||||
|
||||
<th><b>Default</b></th>
|
||||
|
||||
<th align="left"><b>Meaning</b></th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>BOOST_PYTHON_MAX_ARITY</code></td>
|
||||
|
||||
<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
|
||||
<code>x1, 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><R>(</code>...
|
||||
<code>)</code>.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>BOOST_PYTHON_MAX_BASES</code></td>
|
||||
|
||||
<td valign="top" align="center">10</td>
|
||||
|
||||
<td valign="top">The maximum number of template arguments to the
|
||||
<code><a href=
|
||||
"class.html#bases-spec">bases</a><</code>...<code>></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 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>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>BOOST_PYTHON_ENABLE_CDECL</code></td>
|
||||
|
||||
<td valign="top" align="center"><i>not defined</i></td>
|
||||
|
||||
<td valign="top">If defined, allows functions using the <code>__cdecl
|
||||
</code> calling convention to be wrapped.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>BOOST_PYTHON_ENABLE_STDCALL</code></td>
|
||||
|
||||
<td valign="top" align="center"><i>not defined</i></td>
|
||||
|
||||
<td valign="top">If defined, allows functions using the <code>__stdcall
|
||||
</code> calling convention to be wrapped.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>BOOST_PYTHON_ENABLE_FASTCALL</code></td>
|
||||
|
||||
<td valign="top" align="center"><i>not defined</i></td>
|
||||
|
||||
<td valign="top">If defined, allows functions using the <code>__fastcall
|
||||
</code> calling convention to be wrapped.</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>
|
||||
|
||||
<table summary="library defined implementation macros" width="100%"
|
||||
cellpadding="10">
|
||||
<tr>
|
||||
<th align="left"><b>Macro</b></th>
|
||||
|
||||
<th><b>Default</b></th>
|
||||
|
||||
<th align="left"><b>Meaning</b></th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>BOOST_PYTHON_TYPE_ID_NAME</code></td>
|
||||
|
||||
<td valign="top" align="center"><i>not 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>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><code>BOOST_PYTHON_NO_PY_SIGNATURES</code></td>
|
||||
|
||||
<td valign="top" align="center"><i>not defined</i></td>
|
||||
|
||||
<td valign="top">If defined for a module no pythonic signatures are generated
|
||||
for the docstrings of the module functions, and no python type is associated with any
|
||||
of the converters registered by the module. This also reduces the binary size of the
|
||||
module by about 14% (gcc compiled).<br>
|
||||
If defined for the boost_python runtime library, the default for the
|
||||
<code>docstring_options.enable_py_signatures()</code> is set to <code>false</code>.
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><code>BOOST_PYTHON_SUPPORTS_PY_SIGNATURES</code></td>
|
||||
|
||||
<td valign="top" align="center"><i>defined if <code>BOOST_PYTHON_NO_PY_SIGNATURES</code> is undefined</i></td>
|
||||
|
||||
<td valign="top">This macro is defined to enable a smooth transition from older Boost.Python versions
|
||||
which do not support pythonic signatures. For example usage see
|
||||
<a href="pytype_function.html#examples">here</a>.
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top"><code>BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE</code></td>
|
||||
|
||||
<td valign="top" align="center"><i>not defined</i></td>
|
||||
|
||||
<td valign="top">If defined the python type of <code>__init__</code> method "self" parameters
|
||||
is properly generated, otherwise <code><b>object</b></code> is used. It is undefined
|
||||
by default because it increases the binary size of the module by about 14% (gcc compiled).</td>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
7 January, 2003
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
149
doc/v2/copy_const_reference.html
Normal file
@@ -0,0 +1,149 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python -
|
||||
<boost/python/copy_const_reference.hpp></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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header
|
||||
<boost/python/copy_const_reference.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#copy_const_reference-spec">Class
|
||||
<code>copy_const_reference</code></a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#copy_const_reference-spec-synopsis">Class
|
||||
<code>copy_const_reference</code> synopsis</a></dt>
|
||||
|
||||
<dt><a href="#copy_const_reference-spec-metafunctions">Class
|
||||
<code>copy_const_reference</code> metafunctions</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#examples">Example</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="classes"></a>Classes</h2>
|
||||
|
||||
<h3><a name="copy_const_reference-spec"></a>Class
|
||||
<code>copy_const_reference</code></h3>
|
||||
|
||||
<p><code>copy_const_reference</code> is a model of <a href=
|
||||
"ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>
|
||||
which can be used to wrap C++ functions returning a reference-to-const
|
||||
type such that the referenced value is copied into a new Python
|
||||
object.</p>
|
||||
|
||||
<h4><a name="copy_const_reference-spec-synopsis"></a>Class
|
||||
<code>copy_const_reference</code> synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
struct copy_const_reference
|
||||
{
|
||||
template <class T> struct apply;
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="copy_const_reference-spec-metafunctions"></a>Class
|
||||
<code>copy_const_reference</code> metafunctions</h4>
|
||||
<pre>
|
||||
template <class T> struct apply
|
||||
</pre>
|
||||
|
||||
<dl class="metafunction-semantics">
|
||||
<dt><b>Requires:</b> <code>T</code> is <code>U const&</code> for
|
||||
some <code>U</code>.</dt>
|
||||
|
||||
<dt><b>Returns:</b> <code>typedef <a href=
|
||||
"to_python_value.html#to_python_value-spec">to_python_value</a><T>
|
||||
type;</code></dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
|
||||
<h3>C++ Module Definition</h3>
|
||||
<pre>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/copy_const_reference.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
|
||||
// classes to wrap
|
||||
struct Bar { int x; }
|
||||
|
||||
struct Foo {
|
||||
Foo(int x) : { b.x = x; }
|
||||
Bar const& get_bar() const { return b; }
|
||||
private:
|
||||
Bar b;
|
||||
};
|
||||
|
||||
// Wrapper code
|
||||
using namespace boost::python;
|
||||
BOOST_PYTHON_MODULE(my_module)
|
||||
{
|
||||
class_<Bar>("Bar");
|
||||
|
||||
class_<Foo>("Foo", init<int>())
|
||||
.def("get_bar", &Foo::get_bar
|
||||
, return_value_policy<copy_const_reference>())
|
||||
;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>Python Code</h3>
|
||||
<pre>
|
||||
>>> from my_module import *
|
||||
>>> f = Foo(3) # create a Foo object
|
||||
>>> b = f.get_bar() # make a copy of the internal Bar object
|
||||
</pre>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
149
doc/v2/copy_non_const_reference.html
Normal file
@@ -0,0 +1,149 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python -
|
||||
<boost/python/copy_non_const_reference.hpp></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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header
|
||||
<boost/python/copy_non_const_reference.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#copy_non_const_reference-spec">Class
|
||||
<code>copy_non_const_reference</code></a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#copy_non_const_reference-spec-synopsis">Class
|
||||
<code>copy_non_const_reference</code> synopsis</a></dt>
|
||||
|
||||
<dt><a href=
|
||||
"#copy_non_const_reference-spec-metafunctions">Class
|
||||
<code>copy_non_const_reference</code> metafunctions</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#examples">Example</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="classes"></a>Classes</h2>
|
||||
|
||||
<h3><a name="copy_non_const_reference-spec"></a>Class
|
||||
<code>copy_non_const_reference</code></h3>
|
||||
|
||||
<p><code>copy_non_const_reference</code> is a model of <a href=
|
||||
"ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>
|
||||
which can be used to wrap C++ functions returning a
|
||||
reference-to-non-const type such that the referenced value is copied into
|
||||
a new Python object.</p>
|
||||
|
||||
<h4><a name="copy_non_const_reference-spec-synopsis"></a>Class
|
||||
<code>copy_non_const_reference</code> synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
struct copy_non_const_reference
|
||||
{
|
||||
template <class T> struct apply;
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="copy_non_const_reference-spec-metafunctions"></a>Class
|
||||
<code>copy_non_const_reference</code> metafunctions</h4>
|
||||
<pre>
|
||||
template <class T> struct apply
|
||||
</pre>
|
||||
|
||||
<dl class="metafunction-semantics">
|
||||
<dt><b>Requires:</b> <code>T</code> is <code>U&</code> for some
|
||||
non-const <code>U</code>.</dt>
|
||||
|
||||
<dt><b>Returns:</b> <code>typedef <a href=
|
||||
"to_python_value.html#to_python_value-spec">to_python_value</a><T>
|
||||
type;</code></dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
|
||||
<p>C++ code:</p>
|
||||
<pre>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/copy_non_const_reference.hpp>
|
||||
#include <boost/python/return_value_policy.hpp>
|
||||
|
||||
// classes to wrap
|
||||
struct Bar { int x; }
|
||||
|
||||
struct Foo {
|
||||
Foo(int x) : { b.x = x; }
|
||||
Bar& get_bar() { return b; }
|
||||
private:
|
||||
Bar b;
|
||||
};
|
||||
|
||||
// Wrapper code
|
||||
using namespace boost::python;
|
||||
BOOST_PYTHON_MODULE(my_module)
|
||||
{
|
||||
class_<Bar>("Bar");
|
||||
|
||||
class_<Foo>("Foo", init<int>())
|
||||
.def("get_bar", &Foo::get_bar
|
||||
, return_value_policy<copy_non_const_reference>())
|
||||
;
|
||||
}
|
||||
</pre>
|
||||
Python Code:
|
||||
<pre>
|
||||
>>> from my_module import *
|
||||
>>> f = Foo(3) # create a Foo object
|
||||
>>> b = f.get_bar() # make a copy of the internal Bar object
|
||||
</pre>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
229
doc/v2/data_members.html
Normal file
@@ -0,0 +1,229 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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 - <boost/python/data_members.hpp></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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header
|
||||
<boost/python/data_members.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#functions">Functions</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#make_getter-spec">make_getter</a></dt>
|
||||
|
||||
<dt><a href="#make_setter-spec">make_setter</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#examples">Example</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p><code><a href="#make_getter-spec">make_getter</a>()</code> and
|
||||
<code><a href="#make_setter-spec">make_setter</a>()</code> are the
|
||||
functions used internally by <code>class_<>::<a href=
|
||||
"class.html#class_-spec-modifiers">def_readonly</a></code> and
|
||||
<code>class_<>::<a href=
|
||||
"class.html#class_-spec-modifiers">def_readwrite</a></code> to produce
|
||||
Python callable objects which wrap C++ data members.</p>
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
<pre>
|
||||
<a name="make_getter-spec">template <class C, class D></a>
|
||||
<a href="object.html#object-spec">object</a> make_getter(D C::*pm);
|
||||
|
||||
template <class C, class D, class Policies>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_getter(D C::*pm, Policies const& 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 a
|
||||
single argument that can be converted <code>from_python</code> to
|
||||
<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>. 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><></code></dt>
|
||||
|
||||
<dt>for <code>Policies</code>. Note that this test may inappropriately
|
||||
choose <code>return_internal_reference<></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 <class D>
|
||||
<a href="object.html#object-spec">object</a> make_getter(D const& d);
|
||||
template <class D, class Policies>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_getter(D const& d, Policies const& policies);
|
||||
|
||||
template <class D>
|
||||
<a href="object.html#object-spec">object</a> make_getter(D const* p);
|
||||
template <class D, class Policies>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_getter(D const* p, Policies const& 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
|
||||
callable object.</dt>
|
||||
</dl>
|
||||
<pre>
|
||||
<a name="make_setter-spec">template <class C, class D></a>
|
||||
<a href="object.html#object-spec">object</a> make_setter(D C::*pm);
|
||||
|
||||
template <class C, class D, class Policies>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_setter(D C::*pm, Policies const& 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, when called
|
||||
from Python, expects two arguments which can be converted
|
||||
<code>from_python</code> to <code>C*</code> and
|
||||
<code>D const&</code>, respectively, and sets the
|
||||
corresponding <code>D</code> member of the <code>C</code> object. 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>
|
||||
<pre>
|
||||
template <class D>
|
||||
<a href="object.html#object-spec">object</a> make_setter(D& d);
|
||||
template <class D, class Policies>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_setter(D& d, Policies const& policies);
|
||||
|
||||
template <class D>
|
||||
<a href="object.html#object-spec">object</a> make_setter(D* p);
|
||||
template <class D, class Policies>
|
||||
<a href=
|
||||
"object.html#object-spec">object</a> make_setter(D* p, Policies const& 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&</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>
|
||||
|
||||
<p>The code below uses make_getter and make_setter to expose a data
|
||||
member as functions:</p>
|
||||
<pre>
|
||||
#include <boost/python/data_members.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/class.hpp>
|
||||
|
||||
struct X
|
||||
{
|
||||
X(int x) : y(x) {}
|
||||
int y;
|
||||
};
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
BOOST_PYTHON_MODULE_INIT(data_members_example)
|
||||
{
|
||||
class_<X>("X", init<int>())
|
||||
.def("get", make_getter(&X::y))
|
||||
.def("set", make_setter(&X::y))
|
||||
;
|
||||
}
|
||||
</pre>
|
||||
It can be used this way in Python:
|
||||
<pre>
|
||||
>>> from data_members_example import *
|
||||
>>> x = X(1)
|
||||
>>> x.get()
|
||||
1
|
||||
>>> x.set(2)
|
||||
>>> x.get()
|
||||
2
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
5 August, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
191
doc/v2/def.html
Normal file
@@ -0,0 +1,191 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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 - <boost/python/def.hpp></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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/def.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#functions">Functions</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#def-spec">def</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#examples">Example</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p><code><a href="#def-spec">def</a>()</code> is the function which can
|
||||
be used to expose C++ functions and callable objects as Python functions
|
||||
in the current <code><a href="scope.html">scope</a></code>.</p>
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
<a name="def-spec"></a>def
|
||||
<pre>
|
||||
template <class F>
|
||||
void def(char const* name, F f);
|
||||
|
||||
template <class Fn, class A1>
|
||||
void def(char const* name, Fn fn, A1 const&);
|
||||
|
||||
template <class Fn, class A1, class A2>
|
||||
void def(char const* name, Fn fn, A1 const&, A2 const&);
|
||||
|
||||
template <class Fn, class A1, class A2, class A3>
|
||||
void def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);
|
||||
</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>
|
||||
|
||||
<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>,
|
||||
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> function overload
|
||||
to the <a href="scope.html">current scope</a>. 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> contains <em>N</em> types and
|
||||
<code>a1</code> holds <em>M</em> keywords, an initial sequence
|
||||
of the keywords are used for all but the first
|
||||
<em>N</em> - <em>M</em> arguments of each
|
||||
overload.<br>
|
||||
</dt>
|
||||
</dl>
|
||||
</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>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
<pre>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/args.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
char const* foo(int x, int y) { return "foo"; }
|
||||
|
||||
BOOST_PYTHON_MODULE(def_test)
|
||||
{
|
||||
def("foo", foo, args("x", "y"), "foo's docstring");
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
7 March, 2003
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
137
doc/v2/def_visitor.html
Normal file
@@ -0,0 +1,137 @@
|
||||
<!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 - <boost/python/def_visitor.hpp></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="../../../../boost.png" 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 <boost/python/def_visitor.hpp></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><boost/python/def_visitor.hpp></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<T> </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<DerivedVisitor></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, 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 <class DerivedVisitor>
|
||||
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> 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<my_def_visitor>
|
||||
{
|
||||
friend class def_visitor_access;
|
||||
|
||||
template <class classT>
|
||||
void visit(classT& c) const
|
||||
{
|
||||
c
|
||||
.def("foo", &my_def_visitor::foo)
|
||||
.def("bar", &my_def_visitor::bar)
|
||||
;
|
||||
}
|
||||
|
||||
static void foo(X& self);
|
||||
static void bar(X& self);
|
||||
};
|
||||
|
||||
BOOST_PYTHON_MODULE(my_ext)
|
||||
{
|
||||
class_<X>("X")
|
||||
.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>© Copyright Joel de Guzman 2003. </i> Distributed under the Boost
|
||||
Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
173
doc/v2/default_call_policies.html
Normal file
@@ -0,0 +1,173 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<meta name="generator" content="HTML Tidy, 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 -
|
||||
<boost/python/default_call_policies.hpp></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="../../../../boost.png" border="0"></a></h3>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header
|
||||
<boost/python/default_call_policies.hpp></h2>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#classes">Classes</a>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#default_call_policies-spec">Class
|
||||
<code>default_call_policies</code></a>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#default_call_policies-spec-synopsis">Class
|
||||
<code>default_call_policies</code> synopsis</a>
|
||||
|
||||
<dt><a href="#default_call_policies-spec-statics">Class
|
||||
<code>default_call_policies</code> static functions</a>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#default_result_converter-spec">Class
|
||||
<code>default_result_converter</code></a>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#default_result_converter-spec-synopsis">Class
|
||||
<code>default_result_converter</code> synopsis</a>
|
||||
|
||||
<dt><a href="#default_result_converter-spec-metafunctions">Class
|
||||
<code>default_result_converter</code> metafunctions</a>
|
||||
</dl>
|
||||
</dl>
|
||||
|
||||
<dt><a href="#examples">Example</a>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="classes"></a>Classes</h2>
|
||||
|
||||
<h3><a name="default_call_policies-spec"></a>Class
|
||||
<code>default_call_policies</code></h3>
|
||||
|
||||
<p><code>default_call_policies</code> is a model of <a href=
|
||||
"CallPolicies.html">CallPolicies</a> with no <code>precall</code> or
|
||||
<code>postcall</code> behavior and a <code>result_converter</code> which
|
||||
handles by-value returns. Wrapped C++ functions and member functions use
|
||||
<code>default_call_policies</code> unless otherwise specified. You may find
|
||||
it convenient to derive new models of <a href=
|
||||
"CallPolicies.html">CallPolicies</a> from
|
||||
<code>default_call_policies</code>.
|
||||
|
||||
<h4><a name="default_call_policies-spec-synopsis"></a>Class
|
||||
<code>default_call_policies</code> synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
struct default_call_policies
|
||||
{
|
||||
static bool precall(PyObject*);
|
||||
static PyObject* postcall(PyObject*, PyObject* result);
|
||||
typedef <a href=
|
||||
"#default_result_converter-spec">default_result_converter</a> result_converter;
|
||||
template <class Sig> struct extract_return_type : mpl::front<Sig>{};
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="default_call_policies-spec-statics"></a>Class
|
||||
<code>default_call_policies</code> static functions</h4>
|
||||
<pre>
|
||||
bool precall(PyObject*);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Returns:</b> <code>true</code>
|
||||
|
||||
<dt><b>Throws:</b> nothing
|
||||
</dl>
|
||||
<pre>
|
||||
PyObject* postcall(PyObject*, PyObject* result);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Returns:</b> <code>result</code>
|
||||
|
||||
<dt><b>Throws:</b> nothing
|
||||
</dl>
|
||||
|
||||
<h3><a name="default_result_converter-spec"></a>Class
|
||||
<code>default_result_converter</code></h3>
|
||||
|
||||
<p><code>default_result_converter</code> is a model of <a href=
|
||||
"ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a> which can be
|
||||
used to wrap C++ functions returning non-pointer types, <code>char
|
||||
const*</code>, and <code>PyObject*</code>, by-value.
|
||||
|
||||
<h4><a name="default_result_converter-spec-synopsis"></a>Class
|
||||
<code>default_result_converter</code> synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
struct default_result_converter
|
||||
{
|
||||
template <class T> struct apply;
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="default_result_converter-spec-metafunctions"></a>Class
|
||||
<code>default_result_converter</code> metafunctions</h4>
|
||||
<pre>
|
||||
template <class T> struct apply
|
||||
</pre>
|
||||
|
||||
<dl class="metafunction-semantics">
|
||||
<dt><b>Requires:</b> <code>T</code> is not a reference type. If
|
||||
<code>T</code> is a pointer type, <code>T</code> is <code>const
|
||||
char*</code> or <code>PyObject*</code>.
|
||||
|
||||
<dt><b>Returns:</b> <code>typedef <a href=
|
||||
"to_python_value.html#to_python_value-spec">to_python_value</a><T
|
||||
const&> type;</code>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
|
||||
<p>This example comes from the Boost.Python implementation itself. Because
|
||||
the <a href=
|
||||
"return_value_policy.html#return_value_policy-spec">return_value_policy</a>
|
||||
class template does not implement <code>precall</code> or
|
||||
<code>postcall</code> behavior, its default base class is
|
||||
<code>default_call_policies</code>:
|
||||
<pre>
|
||||
template <class Handler, class Base = default_call_policies>
|
||||
struct return_value_policy : Base
|
||||
{
|
||||
typedef Handler result_converter;
|
||||
};
|
||||
</pre>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
11 June, 2007
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
|
||||
|
||||
<p><i>© Copyright <a href="http://www.boost.org/people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002.</i> Distributed under the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)</p>
|
||||
|
||||
102
doc/v2/definitions.html
Normal file
@@ -0,0 +1,102 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - Definitions</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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Definitions</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<dl class="definitions">
|
||||
<dt><b><a name="arity">arity</a>:</b> The number of arguments accepted
|
||||
by a function or member function. Unless otherwise specified, the
|
||||
hidden "<code>this</code>" argument to member functions is not counted
|
||||
when specifying arity</dt>
|
||||
|
||||
<dd><br>
|
||||
</dd>
|
||||
|
||||
<dt><b><a name="ntbs">ntbs</a>:</b> Null-Terminated Byte String, or
|
||||
`C'-string. C++ string literals are <strong>ntbs</strong>es. An
|
||||
<strong>ntbs</strong> must never be null.</dt>
|
||||
|
||||
<dd><br>
|
||||
</dd>
|
||||
|
||||
<dt><b><a name="raise">raise</a>:</b> Exceptions in Python are
|
||||
"raised", not "thrown", as they are in C++. When this documentation
|
||||
says that some Python exception is "raised" in the context of C++ code,
|
||||
it means that the corresponding Python exception is set via the <a
|
||||
href=
|
||||
"http://www.python.org/doc/current/api/exceptionHandling.html">Python/'C'
|
||||
API</a>, and <code><a href=
|
||||
"errors.html#throw_error_already_set-spec">throw_error_already_set</a>()</code>
|
||||
is called.</dt>
|
||||
|
||||
<dd><br>
|
||||
</dd>
|
||||
|
||||
<dt><b><a name="POD">POD</a>:</b> A technical term from the C++
|
||||
standard. Short for "Plain Ol'Data": A POD-struct is an aggregate class
|
||||
that has no non-static data members of type pointer to member,
|
||||
non-POD-struct, non-POD-union (or array of such types) or reference,
|
||||
and has no user-defined copy assign- ment operator and no user-defined
|
||||
destructor. Similarly, a POD-union is an aggregate union that has no
|
||||
non-static data members of type pointer to member, non-POD-struct,
|
||||
non-POD-union (or array of such types) or reference, and has no
|
||||
user-defined copy assignment operator and no user-defined destructor. A
|
||||
POD class is a class that is either a POD-struct or a POD-union. An
|
||||
aggregate is an array or a class (clause 9) with no user-declared
|
||||
constructors (12.1), no private or protected non-static data members
|
||||
(clause 11), no base classes (clause 10), and no virtual functions
|
||||
(10.3).</dt>
|
||||
|
||||
<dd><br>
|
||||
</dd>
|
||||
|
||||
<dt><b><a name="ODR">ODR</a>:</b> The "One Definition
|
||||
Rule", which says that any entity in a C++ program must have the same definition in all translation units (object files) which make up a program.
|
||||
</dt>
|
||||
|
||||
<dd><br>
|
||||
</dd>
|
||||
|
||||
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
152
doc/v2/dict.html
Normal file
@@ -0,0 +1,152 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - <boost/python/dict.hpp></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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/dict.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#dict-spec">Class <code>dict</code></a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#dict-spec-synopsis">Class <code>dict</code>
|
||||
synopsis</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#examples">Example(s)</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p>Exposes a <a href=
|
||||
"ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> for the Python
|
||||
<a href=
|
||||
"http://www.python.org/dev/doc/devel/lib/typesmapping.html">dict</a>
|
||||
type.</p>
|
||||
|
||||
<h2><a name="classes"></a>Classes</h2>
|
||||
|
||||
<h3><a name="dict-spec"></a>Class <code>dict</code></h3>
|
||||
|
||||
<p>Exposes the <a href=
|
||||
"http://www.python.org/dev/doc/devel/lib/typesmapping.html">mapping
|
||||
protocol</a> of Python's built-in <code>dict</code> type. The semantics
|
||||
of the constructors and member functions defined below can be fully
|
||||
understood by reading the <a href=
|
||||
"ObjectWrapper.html#TypeWrapper-concept">TypeWrapper</a> concept
|
||||
definition. Since <code>dict</code> is publicly derived from <code><a
|
||||
href="object.html#object-spec">object</a></code>, the public object
|
||||
interface applies to <code>dict</code> instances as well.</p>
|
||||
|
||||
<h4><a name="dict-spec-synopsis"></a>Class <code>dict</code>
|
||||
synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
class dict : public object
|
||||
{
|
||||
dict();
|
||||
|
||||
template< class T >
|
||||
dict(T const & data);
|
||||
|
||||
// modifiers
|
||||
void clear();
|
||||
dict copy();
|
||||
|
||||
template <class T1, class T2>
|
||||
tuple popitem();
|
||||
|
||||
template <class T>
|
||||
object setdefault(T const &k);
|
||||
|
||||
template <class T1, class T2>
|
||||
object setdefault(T1 const & k, T2 const & d);
|
||||
|
||||
void update(object_cref E);
|
||||
|
||||
template< class T >
|
||||
void update(T const & E);
|
||||
|
||||
// observers
|
||||
list values() const;
|
||||
|
||||
object get(object_cref k) const;
|
||||
|
||||
template<class T>
|
||||
object get(T const & k) const;
|
||||
|
||||
object get(object_cref k, object_cref d) const;
|
||||
object get(T1 const & k, T2 const & d) const;
|
||||
|
||||
bool has_key(object_cref k) const;
|
||||
|
||||
template< class T >
|
||||
bool has_key(T const & k) const;
|
||||
|
||||
list items() const;
|
||||
object iteritems() const;
|
||||
object iterkeys() const;
|
||||
object itervalues() const;
|
||||
list keys() const;
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h2><a name="examples"></a>Example</h2>
|
||||
<pre>
|
||||
using namespace boost::python;
|
||||
dict swap_object_dict(object target, dict d)
|
||||
{
|
||||
dict result = extract<dict>(target.attr("__dict__"));
|
||||
target.attr("__dict__") = d;
|
||||
return result;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Revised 30 September, 2002</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
386
doc/v2/docstring_options.html
Normal file
@@ -0,0 +1,386 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content=
|
||||
"HTML Tidy for Linux/x86 (vers 1st September 2004), 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 -
|
||||
<boost/python/docstring_options.hpp></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="../../../../boost.png" border=
|
||||
"0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href=
|
||||
"../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header
|
||||
<boost/python/docstring_options.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#docstring_options-spec">Class
|
||||
<code>docstring_options</code></a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#docstring_options-spec-synopsis">Class
|
||||
<code>docstring_options</code> synopsis</a></dt>
|
||||
|
||||
<dt><a href="#docstring_options-spec-ctors">Class
|
||||
<code>docstring_options</code> constructors</a></dt>
|
||||
|
||||
<dt><a href="#docstring_options-spec-dtors">Class
|
||||
<code>docstring_options</code> destructors</a></dt>
|
||||
|
||||
<dt><a href="#docstring_options-spec-modifiers">Class
|
||||
<code>docstring_options</code> modifiers</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#examples">Examples</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction" id=
|
||||
"introduction"></a>Introduction</h2>
|
||||
|
||||
<p>Boost.Python supports user-defined docstrings with automatic
|
||||
appending of C++ signatures. These features are enabled by
|
||||
default. The <code>class docstring_options</code> is available to
|
||||
selectively suppress the user-defined docstrings, signatures, or
|
||||
both.</p>
|
||||
|
||||
<h2><a name="classes" id="classes"></a>Classes</h2>
|
||||
|
||||
<h3><a name="docstring_options-spec" id=
|
||||
"docstring_options-spec"></a>Class
|
||||
<code>docstring_options</code></h3>
|
||||
|
||||
<p>Controls the appearance of docstrings of wrapped functions and
|
||||
member functions for the life-time of the instance. The instances
|
||||
are noncopyable to eliminate the possibility of surprising side
|
||||
effects.</p>
|
||||
|
||||
<h4><a name="docstring_options-spec-synopsis" id=
|
||||
"docstring_options-spec-synopsis"></a>Class
|
||||
<code>docstring_options</code> synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python {
|
||||
|
||||
class docstring_options : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
docstring_options(bool show_all=true);
|
||||
|
||||
docstring_options(bool show_user_defined, bool show_signatures);
|
||||
|
||||
docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
|
||||
|
||||
~docstring_options();
|
||||
|
||||
void
|
||||
disable_user_defined();
|
||||
|
||||
void
|
||||
enable_user_defined();
|
||||
|
||||
void
|
||||
disable_signatures();
|
||||
|
||||
void
|
||||
enable_signatures();
|
||||
|
||||
void
|
||||
disable_py_signatures();
|
||||
|
||||
void
|
||||
enable_py_signatures();
|
||||
|
||||
void
|
||||
disable_cpp_signatures();
|
||||
|
||||
void
|
||||
enable_cpp_signatures();
|
||||
|
||||
void
|
||||
disable_all();
|
||||
|
||||
void
|
||||
enable_all();
|
||||
};
|
||||
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="docstring_options-spec-ctors" id=
|
||||
"docstring_options-spec-ctors"></a>Class
|
||||
<code>docstring_options</code> constructors</h4>
|
||||
<pre>
|
||||
docstring_options(bool show_all=true);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Effects:</b> Constructs a <code>docstring_options</code>
|
||||
object which controls the appearance of function and
|
||||
member-function docstrings defined in the code that follows. If
|
||||
<code>show_all</code> is <code>true</code>, both the
|
||||
user-defined docstrings and the automatically generated Python and C++
|
||||
signatures are shown. If <code>show_all</code> is
|
||||
<code>false</code> the <code>__doc__</code> attributes are
|
||||
<code>None</code>.</dt>
|
||||
</dl>
|
||||
<pre>
|
||||
docstring_options(bool show_user_defined, bool show_signatures);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Effects:</b> Constructs a <code>docstring_options</code>
|
||||
object which controls the appearance of function and
|
||||
member-function docstrings defined in the code that follows.
|
||||
Iff <code>show_user_defined</code> is <code>true</code>, the
|
||||
user-defined docstrings are shown. Iff
|
||||
<code>show_signatures</code> is <code>true</code>, Python and C++
|
||||
signatures are automatically added. If both
|
||||
<code>show_user_defined</code> and <code>show_signatures</code>
|
||||
are <code>false</code>, the <code>__doc__</code> attributes are
|
||||
<code>None</code>.</dt>
|
||||
</dl>
|
||||
<pre>
|
||||
docstring_options(bool show_user_defined, bool show_py_signatures, bool show_cpp_signatures);
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Effects:</b> Constructs a <code>docstring_options</code>
|
||||
object which controls the appearance of function and
|
||||
member-function docstrings defined in the code that follows.
|
||||
Iff <code>show_user_defined</code> is <code>true</code>, the
|
||||
user-defined docstrings are shown. Iff
|
||||
<code>show_py_signatures</code> is <code>true</code>, Python
|
||||
signatures are automatically added. Iff
|
||||
<code>show_cpp_signatures</code> is <code>true</code>, C++
|
||||
signatures are automatically added. If all parameters are
|
||||
<code>false</code>, the <code>__doc__</code> attributes are
|
||||
<code>None</code>.</dt>
|
||||
</dl>
|
||||
|
||||
<h4><a name="docstring_options-spec-dtors" id=
|
||||
"docstring_options-spec-dtors"></a>Class
|
||||
<code>docstring_options</code> destructors</h4>
|
||||
<pre>
|
||||
~docstring_options();
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt><b>Effects:</b> Restores the previous state of the
|
||||
docstring options. In particular, if
|
||||
<code>docstring_options</code> instances are in nested C++
|
||||
scopes the settings effective in the enclosing scope are
|
||||
restored. If the last <code>docstring_options</code> instance
|
||||
goes out of scope the default "all on" settings are
|
||||
restored.</dt>
|
||||
</dl>
|
||||
|
||||
<h4><a name="docstring_options-spec-modifiers" id=
|
||||
"docstring_options-spec-modifiers"></a>Class
|
||||
<code>docstring_options</code> modifier functions</h4>
|
||||
<pre>
|
||||
void disable_user_defined();
|
||||
void enable_user_defined();
|
||||
void disable_signatures();
|
||||
void enable_signatures();
|
||||
void disable_py_signatures();
|
||||
void enable_py_signatures();
|
||||
void disable_cpp_signatures();
|
||||
void enable_cpp_signatures();
|
||||
void disable_all();
|
||||
void enable_all();
|
||||
</pre>
|
||||
|
||||
<dl class="function-semantics">
|
||||
<dt>These member functions dynamically change the appearance of
|
||||
docstrings in the code that follows. The
|
||||
<code>*_user_defined()</code> and <code>*_signatures()</code>
|
||||
member functions are provided for fine-grained control. The
|
||||
<code>*_all()</code> member functions are convenient shortcuts
|
||||
to manipulate all settings simultaneously.</dt>
|
||||
</dl>
|
||||
|
||||
<h2><a name="examples" id="examples"></a>Examples</h2>
|
||||
|
||||
<h4>Docstring options defined at compile time</h4>
|
||||
<pre>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/docstring_options.hpp>
|
||||
|
||||
void foo() {}
|
||||
|
||||
BOOST_PYTHON_MODULE(demo)
|
||||
{
|
||||
using namespace boost::python;
|
||||
docstring_options doc_options(DEMO_DOCSTRING_SHOW_ALL);
|
||||
def("foo", foo, "foo doc");
|
||||
}
|
||||
</pre>If compiled with <code>-DDEMO_DOCSTRING_SHOW_ALL=true</code>:
|
||||
<pre>
|
||||
>>> import demo
|
||||
>>> print demo.foo.__doc__
|
||||
foo() -> None : foo doc
|
||||
C++ signature:
|
||||
foo(void) -> void
|
||||
</pre>If compiled with
|
||||
<code>-DDEMO_DOCSTRING_SHOW_ALL=false</code>:
|
||||
<pre>
|
||||
>>> import demo
|
||||
>>> print demo.foo.__doc__
|
||||
None
|
||||
</pre>
|
||||
|
||||
<h4>Selective suppressions</h4>
|
||||
<pre>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/args.hpp>
|
||||
#include <boost/python/docstring_options.hpp>
|
||||
|
||||
int foo1(int i) { return i; }
|
||||
int foo2(long l) { return static_cast<int>(l); }
|
||||
int foo3(float f) { return static_cast<int>(f); }
|
||||
int foo4(double d) { return static_cast<int>(d); }
|
||||
|
||||
BOOST_PYTHON_MODULE(demo)
|
||||
{
|
||||
using namespace boost::python;
|
||||
docstring_options doc_options;
|
||||
def("foo1", foo1, arg("i"), "foo1 doc");
|
||||
doc_options.disable_user_defined();
|
||||
def("foo2", foo2, arg("l"), "foo2 doc");
|
||||
doc_options.disable_signatures();
|
||||
def("foo3", foo3, arg("f"), "foo3 doc");
|
||||
doc_options.enable_user_defined();
|
||||
def("foo4", foo4, arg("d"), "foo4 doc");
|
||||
doc_options.enable_py_signatures();
|
||||
def("foo5", foo4, arg("d"), "foo5 doc");
|
||||
doc_options.disable_py_signatures();
|
||||
doc_options.enable_cpp_signatures();
|
||||
def("foo6", foo4, arg("d"), "foo6 doc");
|
||||
}
|
||||
</pre>Python code:
|
||||
<pre>
|
||||
>>> import demo
|
||||
>>> print demo.foo1.__doc__
|
||||
foo1( (int)i) -> int : foo1 doc
|
||||
C++ signature:
|
||||
foo1(int i) -> int
|
||||
>>> print demo.foo2.__doc__
|
||||
foo2( (int)l) -> int :
|
||||
C++ signature:
|
||||
foo2(long l) -> int
|
||||
>>> print demo.foo3.__doc__
|
||||
None
|
||||
>>> print demo.foo4.__doc__
|
||||
foo4 doc
|
||||
>>> print demo.foo5.__doc__
|
||||
foo5( (float)d) -> int : foo5 doc
|
||||
>>> print demo.foo6.__doc__
|
||||
foo6 doc
|
||||
C++ signature:
|
||||
foo6(double d) -> int
|
||||
</pre>
|
||||
|
||||
<h4>Wrapping from multiple C++ scopes</h4>
|
||||
<pre>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/args.hpp>
|
||||
#include <boost/python/docstring_options.hpp>
|
||||
|
||||
int foo1(int i) { return i; }
|
||||
int foo2(long l) { return static_cast<int>(l); }
|
||||
|
||||
int bar1(int i) { return i; }
|
||||
int bar2(long l) { return static_cast<int>(l); }
|
||||
|
||||
namespace {
|
||||
|
||||
void wrap_foos()
|
||||
{
|
||||
using namespace boost::python;
|
||||
// no docstring_options here
|
||||
// -> settings from outer C++ scope are in effect
|
||||
def("foo1", foo1, arg("i"), "foo1 doc");
|
||||
def("foo2", foo2, arg("l"), "foo2 doc");
|
||||
}
|
||||
|
||||
void wrap_bars()
|
||||
{
|
||||
using namespace boost::python;
|
||||
bool show_user_defined = true;
|
||||
bool show_signatures = false;
|
||||
docstring_options doc_options(show_user_defined, show_signatures);
|
||||
def("bar1", bar1, arg("i"), "bar1 doc");
|
||||
def("bar2", bar2, arg("l"), "bar2 doc");
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(demo)
|
||||
{
|
||||
boost::python::docstring_options doc_options(false);
|
||||
wrap_foos();
|
||||
wrap_bars();
|
||||
}
|
||||
</pre>Python code:
|
||||
<pre>
|
||||
>>> import demo
|
||||
>>> print demo.foo1.__doc__
|
||||
None
|
||||
>>> print demo.foo2.__doc__
|
||||
None
|
||||
>>> print demo.bar1.__doc__
|
||||
bar1 doc
|
||||
>>> print demo.bar2.__doc__
|
||||
bar2 doc
|
||||
</pre>
|
||||
|
||||
<h4>See also: <code>boost/libs/python/test/docstring.cpp</code>
|
||||
and <code>docstring.py</code></h4>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
16 January, 2006
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" --></p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/ralf_w_grosse_kunstleve.htm">Ralf W.
|
||||
Grosse-Kunstleve</a> 2006.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
234
doc/v2/enum.html
Normal file
@@ -0,0 +1,234 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
|
||||
<!-- Software License, Version 1.0. (See accompanying -->
|
||||
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
|
||||
<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">
|
||||
<link rel="stylesheet" type="text/css" href="../boost.css">
|
||||
|
||||
<title>Boost.Python - <boost/python/enum.hpp></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="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/enum.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="page-index">
|
||||
<dt><a href="#introduction">Introduction</a></dt>
|
||||
|
||||
<dt><a href="#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#enum_-spec">Class template
|
||||
<code>enum_</code></a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#enum_-spec-synopsis">Class template <code>enum_</code>
|
||||
synopsis</a></dt>
|
||||
|
||||
<dt><a href="#enum_-spec-ctors">Class template <code>enum_</code>
|
||||
constructors</a></dt>
|
||||
|
||||
<dt><a href="#enum_-spec-modifiers">Class template <code>enum_</code>
|
||||
modifier functions</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#examples">Example(s)</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p><code><boost/python/enum.hpp></code> defines the
|
||||
interface through which users expose their C++ enumeration types
|
||||
to Python. It declares the
|
||||
<code>enum_</code> class template, which is parameterized on the
|
||||
enumeration type being exposed. </p>
|
||||
|
||||
|
||||
<h2><a name="classes"></a>Classes</h2>
|
||||
|
||||
<h3><a name="enum_-spec"></a>Class template
|
||||
<code>enum_<T></code></h3>
|
||||
|
||||
<p>Creates a Python class derived from Python's <code>int</code>
|
||||
type which is associated with the C++ type passed as its first
|
||||
parameter.
|
||||
|
||||
<h4><a name="enum_-spec-synopsis"></a>Class template <code>enum_</code>
|
||||
synopsis</h4>
|
||||
<pre>
|
||||
namespace boost { namespace python
|
||||
{
|
||||
template <class T>
|
||||
class enum_ : public <a href="object.html#object-spec">object</a>
|
||||
{
|
||||
enum_(char const* name, char const* doc = 0);
|
||||
enum_<T>& value(char const* name, T);
|
||||
enum_<T>& export_values();
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
|
||||
<h4><a name="enum_-spec-ctors"></a>Class template <code>enum_</code>
|
||||
constructors</h4>
|
||||
<pre>
|
||||
enum_(char const* name, char const* doc=0);
|
||||
</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><b>Effects:</b> Constructs an <code>enum_</code> object
|
||||
holding a Python extension type derived from <code>int</code>
|
||||
which is named <code>name</code>. The
|
||||
<code>name</code>d attribute of the <a href=
|
||||
"scope.html#introduction">current scope</a> is bound to the new
|
||||
extension type.</dt>
|
||||
</dl>
|
||||
|
||||
<h4><a name="enum_-spec-modifiers"></a>Class template
|
||||
<code>enum_</code> modifier functions</h4>
|
||||
<pre>
|
||||
inline enum_<T>& value(char const* name, T x);
|
||||
</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><b>Effects:</b> adds an instance of the wrapped enumeration
|
||||
type with value <code>x</code> to the type's dictionary as the
|
||||
<code>name</code>d attribute.</dt>
|
||||
|
||||
<dt><b>Returns:</b> <code>*this</code></dt>
|
||||
|
||||
</dl>
|
||||
|
||||
<pre>
|
||||
inline enum_<T>& 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
|
||||
<pre>
|
||||
#include <boost/python/enum.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
enum color { red = 1, green = 2, blue = 4 };
|
||||
|
||||
color identity_(color x) { return x; }
|
||||
|
||||
BOOST_PYTHON_MODULE(enums)
|
||||
{
|
||||
enum_<color>("color")
|
||||
.value("red", red)
|
||||
.value("green", green)
|
||||
.export_values()
|
||||
.value("blue", blue)
|
||||
;
|
||||
|
||||
def("identity", identity_);
|
||||
}
|
||||
</pre>
|
||||
<p>Interactive Python:
|
||||
<pre>
|
||||
>>> from enums import *
|
||||
|
||||
>>> identity(red)
|
||||
enums.color.red
|
||||
|
||||
>>> identity(color.red)
|
||||
enums.color.red
|
||||
|
||||
>>> identity(green)
|
||||
enums.color.green
|
||||
|
||||
>>> identity(color.green)
|
||||
enums.color.green
|
||||
|
||||
>>> identity(blue)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
NameError: name blue' is not defined
|
||||
|
||||
>>> identity(color.blue)
|
||||
enums.color.blue
|
||||
|
||||
>>> identity(color(1))
|
||||
enums.color.red
|
||||
|
||||
>>> identity(color(2))
|
||||
enums.color.green
|
||||
|
||||
>>> identity(color(3))
|
||||
enums.color(3)
|
||||
|
||||
>>> identity(color(4))
|
||||
enums.color.blue
|
||||
|
||||
>>> identity(1)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: bad argument type for built-in operation
|
||||
</pre>
|
||||
<hr>
|
||||
|
||||
Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
13 December, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||