Compare commits
965 Commits
boost-1.29
...
boost-1.34
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee82e4e006 | ||
|
|
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 |
@@ -1,66 +0,0 @@
|
||||
# (C) Copyright David Abrahams 2001. 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.
|
||||
#
|
||||
# Boost.Python library Jamfile
|
||||
|
||||
|
||||
# declare the location of this subproject relative to the root
|
||||
subproject libs/python/build ;
|
||||
|
||||
# bring in the rules for python
|
||||
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include <module@>python.jam ;
|
||||
|
||||
if [ check-python-config ]
|
||||
{
|
||||
|
||||
local bpl-linkflags ;
|
||||
|
||||
if $(UNIX) && ( $(OS) = AIX )
|
||||
{
|
||||
bpl-linkflags = <linkflags>"-e initlibboost_python" ;
|
||||
}
|
||||
|
||||
dll boost_python
|
||||
:
|
||||
../src/numeric.cpp
|
||||
|
||||
../src/list.cpp
|
||||
../src/long.cpp
|
||||
../src/dict.cpp
|
||||
../src/tuple.cpp
|
||||
../src/str.cpp
|
||||
|
||||
../src/aix_init_module.cpp
|
||||
../src/converter/from_python.cpp
|
||||
../src/converter/registry.cpp
|
||||
../src/converter/type_id.cpp
|
||||
../src/object/enum.cpp
|
||||
../src/object/class.cpp
|
||||
../src/object/function.cpp
|
||||
../src/object/inheritance.cpp
|
||||
../src/object/life_support.cpp
|
||||
../src/object/pickle_support.cpp
|
||||
../src/errors.cpp
|
||||
../src/module.cpp
|
||||
../src/converter/builtin_converters.cpp
|
||||
../src/converter/arg_to_python_base.cpp
|
||||
../src/object/iterator.cpp
|
||||
../src/object_protocol.cpp
|
||||
../src/object_operators.cpp
|
||||
:
|
||||
$(BOOST_PYTHON_V2_PROPERTIES)
|
||||
<define>BOOST_PYTHON_SOURCE
|
||||
$(bpl-linkflags)
|
||||
;
|
||||
|
||||
stage bin-stage : <dll>boost_python
|
||||
:
|
||||
<tag><debug>"_debug"
|
||||
<tag><debug-python>"_pydebug"
|
||||
:
|
||||
debug release
|
||||
;
|
||||
}
|
||||
93
build/Jamfile.v2
Normal file
@@ -0,0 +1,93 @@
|
||||
# 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 modules ;
|
||||
|
||||
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" ;
|
||||
}
|
||||
}
|
||||
|
||||
if [ python.configured ] {
|
||||
|
||||
project boost/python
|
||||
: source-location ../src
|
||||
;
|
||||
|
||||
lib boost_python
|
||||
: # sources
|
||||
numeric.cpp
|
||||
list.cpp
|
||||
long.cpp
|
||||
dict.cpp
|
||||
tuple.cpp
|
||||
str.cpp
|
||||
slice.cpp
|
||||
|
||||
aix_init_module.cpp
|
||||
converter/from_python.cpp
|
||||
converter/registry.cpp
|
||||
converter/type_id.cpp
|
||||
object/enum.cpp
|
||||
object/class.cpp
|
||||
object/function.cpp
|
||||
object/inheritance.cpp
|
||||
object/life_support.cpp
|
||||
object/pickle_support.cpp
|
||||
errors.cpp
|
||||
module.cpp
|
||||
converter/builtin_converters.cpp
|
||||
converter/arg_to_python_base.cpp
|
||||
object/iterator.cpp
|
||||
object/stl_iterator.cpp
|
||||
object_protocol.cpp
|
||||
object_operators.cpp
|
||||
wrapper.cpp
|
||||
import.cpp
|
||||
exec.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.
|
||||
<library>/python//python_for_extensions
|
||||
|
||||
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
|
||||
|
||||
: # default build
|
||||
<link>shared
|
||||
: # usage requirements
|
||||
<link>static:<define>BOOST_PYTHON_STATIC_LIB
|
||||
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
ECHO "warning: Python location is not configured" ;
|
||||
ECHO "warning: the Boost.Python library won't be built" ;
|
||||
}
|
||||
910
build/VisualStudio/boost_python.dsp
Normal file
@@ -0,0 +1,910 @@
|
||||
# Microsoft Developer Studio Project File - Name="boost_python" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=BOOST_PYTHON - WIN32 RELEASE
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "boost_python.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "boost_python.mak" CFG="BOOST_PYTHON - WIN32 RELEASE"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "boost_python - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "boost_python - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "boost_python - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "../bin-stage"
|
||||
# PROP Intermediate_Dir "release-obj"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
F90=df.exe
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BPL_EXPORTS" /YX /FD /Zm800 /Zm800 /Zm800 /c
|
||||
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../../" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOOST_PYTHON_DYNAMIC_LIB" /D "BOOST_PYTHON_SOURCE" /FD /Zm800 /Zm800 /Zm800 /Zm800 /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x1409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x1409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib /nologo /dll /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "boost_python - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "../bin-stage"
|
||||
# PROP Intermediate_Dir "debug-obj"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
F90=df.exe
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BPL_EXPORTS" /YX /FD /Zm800 /Zm800 /Zm800 /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /GR /GX /Zi /Od /I "../../../../" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BOOST_PYTHON_DYNAMIC_LIB" /D "BOOST_PYTHON_SOURCE" /FD /Zm800 /Zm800 /Zm800 /Zm800 /Zm800 /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x1409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x1409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib /nologo /dll /incremental:no /debug /machine:I386 /out:"../bin-stage/boost_python_debug.dll" /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "boost_python - Win32 Release"
|
||||
# Name "boost_python - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\aix_init_module.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\converter\arg_to_python_base.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\converter\builtin_converters.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\object\class.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\dict.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\object\enum.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\errors.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\converter\from_python.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\object\function.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\object\inheritance.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\object\iterator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\object\life_support.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\list.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\long.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\module.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\numeric.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\object_operators.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\object_protocol.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\object\pickle_support.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\converter\registry.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\slice.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\object\stl_iterator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\str.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\tuple.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\converter\type_id.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\wrapper.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\import.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\exec.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Group "detail"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\aix_init_module.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\api_placeholder.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\arg_tuple_size.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\borrowed_ptr.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\call_object.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\caller.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\char_array.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\config.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\construct.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\convertible.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\cv_category.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\decorated_type_id.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\def_helper.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\defaults_def.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\defaults_gen.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\dependent.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\destroy.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\exception_handler.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\force_instantiate.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\if_else.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\indirect_traits.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\make_keyword_range_fn.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\make_tuple.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\map_entry.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\member_function_cast.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\module_base.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\module_init.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\msvc_typeinfo.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\none.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\not_specified.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\operator_id.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\overloads_fwd.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\pointee.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\preprocessor.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\python22_fixed.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\raw_pyobject.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\referent_storage.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\result.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\returning.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\scope.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\string_literal.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\target.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\translate_exception.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\type_list.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\type_list_impl.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\type_list_impl_no_pts.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\type_list_utils.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\unwind_type.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\void_ptr.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\void_return.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\detail\wrap_python.hpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "converter"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\arg_from_python.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\arg_to_python.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\arg_to_python_base.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\builtin_converters.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\constructor_function.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\convertible_function.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\from_python.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\implicit.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\obj_mgr_arg_from_python.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\object_manager.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\pointer_type_id.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\pyobject_traits.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\pyobject_type.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\pytype_arg_from_python.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\pytype_object_mgr_traits.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\registered.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\registered_pointee.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\registrations.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\registry.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\return_from_python.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\rvalue_from_python_data.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\converter\to_python_function_type.hpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "object"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\add_to_namespace.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\class.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\class_converters.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\class_detail.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\class_wrapper.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\construct.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\enum_base.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\find_instance.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\forward.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\function.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\function_handle.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\function_object.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\inheritance.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\instance.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\iterator.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\iterator_core.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\life_support.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\make_holder.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\make_instance.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\pickle_support.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\pointer_holder.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\py_function.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\select_holder.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\stl_iterator_core.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\value_holder.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object\value_holder_fwd.hpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\arg_from_python.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\args.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\args_fwd.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\back_reference.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\base_type_traits.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\bases.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\borrowed.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\call.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\call_method.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\cast.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\class.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\class_fwd.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\copy_const_reference.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\copy_non_const_reference.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\data_members.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\def.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\default_call_policies.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\dict.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\enum.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\errors.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\exception_translator.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\extract.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\handle.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\handle_fwd.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\has_back_reference.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\implicit.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\init.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\instance_holder.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\iterator.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\list.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\long.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\lvalue_from_pytype.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\make_function.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\manage_new_object.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\module.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\module_init.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\numeric.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object_attributes.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object_call.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object_core.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object_fwd.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object_items.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object_operators.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object_protocol.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object_protocol_core.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\object_slices.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\operators.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\operators2.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\other.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\overloads.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\pointee.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\proxy.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\ptr.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\refcount.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\reference_existing_object.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\return_internal_reference.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\return_value_policy.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\scope.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\self.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\signature.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\slice_nil.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\stl_iterator.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\str.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\tag.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\to_python_converter.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\to_python_indirect.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\to_python_value.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\tuple.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\type_id.hpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\..\boost\python\with_custodian_and_ward.hpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
29
build/VisualStudio/boost_python.dsw
Normal file
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "boost_python"=".\boost_python.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
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
Executable 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
Executable 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
Executable file
|
After Width: | Height: | Size: 22 KiB |
BIN
doc/PyConDC_2003/python_cpp_mix.png
Executable file
|
After Width: | Height: | Size: 6.1 KiB |
@@ -1,3 +1,7 @@
|
||||
/* 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%
|
||||
|
||||
@@ -1,294 +1,647 @@
|
||||
<!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.htm"><img alt="Boost C++ Libraries:" class="boost-logo" src="../../../boost.png" /></a> Boost.Python Build and Test HOWTO</h1>
|
||||
|
||||
<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">
|
||||
<!-- 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">
|
||||
<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>Boost.Python - Building and Testing</title>
|
||||
</head>
|
||||
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
|
||||
"C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
|
||||
<h2 align="center">Building and Testing</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="Reference">
|
||||
<dt><a href="#requirements">Requirements</a></dt>
|
||||
|
||||
<dt><a href="#building">Building Boost.Python</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="index">
|
||||
<dt><a href="#configuration">Configuration</a></dt>
|
||||
|
||||
<dt><a href="#results">Results</a></dt>
|
||||
|
||||
<dt><a href="#testing">Testing</a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#building_ext">Building your Extension Module</a></dt>
|
||||
|
||||
<dt><a href="#variants">Build Variants</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<h2><a name="requirements">Requirements</a></h2>
|
||||
Boost.Python requires <a href="http://www.python.org">Python</a> 2.2 or
|
||||
later.
|
||||
|
||||
<h2><a name="building">Building Boost.Python</a></h2>
|
||||
|
||||
<p>Every Boost.Python extension module must be linked with the
|
||||
<code>boost_python</code> shared library. To build
|
||||
<code>boost_python</code>, use <a href=
|
||||
"../../../tools/build/index.html">Boost.Build</a> in the usual way from
|
||||
the <code>libs/python/build</code> subdirectory of your boost
|
||||
installation (if you have already built boost from the top level this may
|
||||
have no effect, since the work is already done).</p>
|
||||
|
||||
<h3><a name="configuration">Configuration</a></h3>
|
||||
You may need to configure the following variables to point Boost.Build at
|
||||
your Python installation:
|
||||
|
||||
<table border="1" summary="build configuration variables">
|
||||
<tr>
|
||||
<th>Variable Name</th>
|
||||
|
||||
<th>Semantics</th>
|
||||
|
||||
<th>Default</th>
|
||||
|
||||
<th>Notes</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>PYTHON_ROOT</code></td>
|
||||
|
||||
<td>The root directory of your Python installation</td>
|
||||
|
||||
<td>Windows: <code>c:/tools/python</code>
|
||||
Unix: <code>/usr/local</code></td>
|
||||
|
||||
<td>On Unix, this is the <code>--with-prefix=</code> directory used
|
||||
to configure Python</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>PYTHON_VERSION</code></td>
|
||||
|
||||
<td>The The 2-part python Major.Minor version number</td>
|
||||
|
||||
<td><code>2.2</code></td>
|
||||
|
||||
<td>Be sure not to include a third number, e.g. <b>not</b>
|
||||
"<code>2.2.1</code>", even if that's the version you have.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>PYTHON_INCLUDES</code></td>
|
||||
|
||||
<td>path to Python <code>#include</code> directories</td>
|
||||
|
||||
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>PYTHON_LIB_PATH</code></td>
|
||||
|
||||
<td>path to Python library object.</td>
|
||||
|
||||
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>PYTHON_STDLIB_PATH</code></td>
|
||||
|
||||
<td>path to Python standard library modules</td>
|
||||
|
||||
<td>Autoconfigured from <code>PYTHON_ROOT</code></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>CYGWIN_ROOT</code></td>
|
||||
|
||||
<td>path to the user's Cygwin installation</td>
|
||||
|
||||
<td>
|
||||
</td>
|
||||
|
||||
<td><a href="http://www.cygwin.com">Cygwin</a> only. This and the
|
||||
following two settings are useful when building with multiple
|
||||
toolsets on Windows, since Cygwin requires a different build of
|
||||
Python.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>GCC_PYTHON_ROOT</code></td>
|
||||
|
||||
<td>path to the user's Cygwin Python installation</td>
|
||||
|
||||
<td><code>$(CYGWIN_ROOT)/usr/local</code></td>
|
||||
|
||||
<td><a href="http://www.cygwin.com">Cygwin</a> only</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><code>GCC_DEBUG_PYTHON_ROOT</code></td>
|
||||
|
||||
<td>path to the user's Cygwin <code><a href=
|
||||
"#variants">pydebug</a></code> build</td>
|
||||
|
||||
<td><code>$(CYGWIN_ROOT)/usr/local/pydebug</code></td>
|
||||
|
||||
<td><a href="http://www.cygwin.com">Cygwin</a> only</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3><a name="results">Results</a></h3>
|
||||
|
||||
<p>The build process will create a
|
||||
<code>libs/python/build/bin-stage</code> subdirectory of the boost root
|
||||
(or of <code>$(ALL_LOCATE_TARGET)</code>, if you have set that variable),
|
||||
containing the built libraries. The libraries are actually built to
|
||||
unique directories for each toolset and variant elsewhere in the
|
||||
filesystem, and copied to the <code>bin-stage</code> directory as a
|
||||
convenience, so if you build with multiple toolsets at once, the product
|
||||
of later toolsets will overwrite that of earlier toolsets in
|
||||
<code>bin-stage</code>.</p>
|
||||
|
||||
<h3><a name="testing">Testing</a></h3>
|
||||
|
||||
<p>To build and test Boost.Python, start from the
|
||||
<code>libs/python/test</code> directory and invoke</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
bjam -sTOOLS=<i><a href=
|
||||
"../../../tools/build/index.html#Tools">toolset</a></i> test
|
||||
<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>
|
||||
</blockquote>
|
||||
This will update all of the Boost.Python v1 test and example targets. The
|
||||
tests are relatively quiet by default. To get more-verbose output, you
|
||||
might try
|
||||
<p 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
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
bjam -sTOOLS=<i><a href=
|
||||
"../../../tools/build/index.html#Tools">toolset</a></i> -sPYTHON_TEST_ARGS=-v test
|
||||
</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>
|
||||
</blockquote>
|
||||
which will print each test's Python code with the expected output as it
|
||||
passes.
|
||||
<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="../../../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="../../../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 class="admonition-windows-users-no-auto-link-support admonition">
|
||||
<p class="first admonition-title">Windows Users: No Auto-Link Support</p>
|
||||
<p class="last">Boost.Python does not yet support the <a class="reference external" href="../../../more/getting_started/windows.html#link-your-program-to-a-boost-library">auto-link</a> feature, so if
|
||||
you're not using the <a class="reference internal" href="#no-install-quickstart">quickstart</a> method, you'll have to pay
|
||||
attention to the names of generated libraries and add extra link
|
||||
arguments not shown in the <a class="reference external" href="../../../more/getting_started/index.html">Getting Started Guide</a> to select the
|
||||
right library.</p>
|
||||
</div>
|
||||
</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="#no-install-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
|
||||
|
||||
<h2><a name="building_ext">Building your Extension Module</a></h2>
|
||||
Though there are other approaches, the easiest way to build an extension
|
||||
module using Boost.Python is with Boost.Build. Until Boost.Build v2 is
|
||||
released, cross-project build dependencies are not supported, so it works
|
||||
most smoothly if you add a new subproject to your boost installation. The
|
||||
<code>libs/python/example</code> subdirectory of your boost installation
|
||||
contains a minimal example (along with many extra sources). To copy the
|
||||
example subproject:
|
||||
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
|
||||
|
||||
<ol>
|
||||
<li>Create a new subdirectory in, <code>libs/python</code>, say
|
||||
<code>libs/python/my_project</code>.</li>
|
||||
# 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 ;
|
||||
|
||||
<li>Copy <code><a href=
|
||||
"../example/Jamfile">libs/python/example/Jamfile</a></code> to your new
|
||||
directory.</li>
|
||||
# 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>
|
||||
<p class="last">Be sure to read this section even if your compiler supports
|
||||
auto-linking, as Boost.Python does not yet take advantage of
|
||||
that feature.</p>
|
||||
</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.
|
||||
You may also find</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-05-07 18:58 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.
|
||||
|
||||
<li>Edit the Jamfile as appropriate for your project. You'll want to
|
||||
change the "<code>subproject</code>" rule invocation at the top, and
|
||||
the names of some of the source files and/or targets.</li>
|
||||
</ol>
|
||||
If you can't modify or copy your boost installation, the alternative is
|
||||
to create your own Boost.Build project. A similar example you can use as
|
||||
a starting point is available in <code><a href=
|
||||
"../example/project.zip">this archive</a></code>. You'll need to edit the
|
||||
Jamfile and Jamrules files, depending on the relative location of your
|
||||
Boost installation and the new project. Note that automatic testing of
|
||||
extension modules is not available in this configuration.
|
||||
|
||||
<h2><a name="variants">Build Variants</a></h2>
|
||||
Three <a href=
|
||||
"../../../tools/build/build_system.htm#variants">variant</a>
|
||||
configurations of all python-related targets are supported, and can be
|
||||
selected by setting the <code><a href=
|
||||
"../../../tools/build/build_system.htm#user_globals">BUILD</a></code>
|
||||
variable:
|
||||
|
||||
<ul>
|
||||
<li><code>release</code> (optimization, <tt>-DNDEBUG</tt>)</li>
|
||||
|
||||
<li><code>debug</code> (no optimization <tt>-D_DEBUG</tt>)</li>
|
||||
|
||||
<li><code>debug-python</code> (no optimization, <tt>-D_DEBUG
|
||||
-DBOOST_DEBUG_PYTHON</tt>)</li>
|
||||
</ul>
|
||||
|
||||
<p>The first two variants of the <code>boost_python</code> library are
|
||||
built by default, and are compatible with the default Python
|
||||
distribution. The <code>debug-python</code> variant corresponds to a
|
||||
specially-built debugging version of Python. On Unix platforms, this
|
||||
python is built by adding <code>--with-pydebug</code> when configuring
|
||||
the Python build. On Windows, the debugging version of Python is
|
||||
generated by the "Win32 Debug" target of the <code>PCBuild.dsw</code>
|
||||
Visual C++ 6.0 project in the <code>PCBuild</code> subdirectory of your
|
||||
Python distribution. Extension modules built with Python debugging
|
||||
enabled are <b>not link-compatible</b> with a non-debug build of Python.
|
||||
Since few people actually have a debug build of Python (it doesn't come
|
||||
with the standard distribution), the normal <code>debug</code> variant
|
||||
builds modules which are compatible with ordinary Python.</p>
|
||||
|
||||
<p>On many windows compilers, when extension modules are built with
|
||||
<tt>-D_DEBUG</tt>, Python defaults to <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 - unless <code>BOOST_DEBUG_PYTHON</code> is
|
||||
defined.</p>
|
||||
|
||||
<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
|
||||
python debuggin, and link with the <code>debug-python</code> variant of
|
||||
<tt>boost_python</tt>.</p>
|
||||
|
||||
<p>If you do not <tt>#define BOOST_DEBUG_PYTHON</tt>, be sure that any
|
||||
source files in your extension module <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>
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
<p>© Copyright David Abrahams 2002. 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>
|
||||
|
||||
<p>Updated: O8 October, 2002 (David Abrahams)</p>
|
||||
</body>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
694
doc/building.rst
Normal file
@@ -0,0 +1,694 @@
|
||||
.. 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.htm
|
||||
|
||||
|
||||
.. 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()``.
|
||||
|
||||
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
|
||||
|
||||
__ ../../../more/mailing_lists.htm#jamboost
|
||||
__ ../../../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.
|
||||
|
||||
.. Admonition:: Windows Users: No Auto-Link Support
|
||||
|
||||
Boost.Python does not yet support the `auto-link`_ feature, so if
|
||||
you're not using the quickstart_ method, you'll have to pay
|
||||
attention to the names of generated libraries and add extra link
|
||||
arguments not shown in the `Getting Started Guide`_ to select the
|
||||
right library.
|
||||
|
||||
.. _auto-link: ../../../more/getting_started/windows.html#link-your-program-to-a-boost-library
|
||||
|
||||
.. _quickstart: `no-install quickstart`_
|
||||
|
||||
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
|
||||
|
||||
Be sure to read this section even if your compiler supports
|
||||
auto-linking, as Boost.Python does not yet take advantage of
|
||||
that feature.
|
||||
|
||||
.. [#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.
|
||||
You may also find
|
||||
140
doc/index.html
@@ -1,11 +1,14 @@
|
||||
<!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">
|
||||
<link rel="stylesheet" type="text/css" href="../../../boost.css">
|
||||
|
||||
<title>Boost.Python</title>
|
||||
</head>
|
||||
@@ -16,7 +19,7 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../index.htm"><img height="86" width="277" alt=
|
||||
"C++ Boost" src="../../../c++boost.gif" border="0"></a></h3>
|
||||
"C++ Boost" src="../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
@@ -24,10 +27,96 @@
|
||||
|
||||
<h2 align="center">Index</h2>
|
||||
</td>
|
||||
|
||||
|
||||
<td align="right">
|
||||
|
||||
<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>
|
||||
|
||||
<span id="search-text">
|
||||
<input type="text" name="q" id="q" size="31" maxlength="255" alt="Search Text" />
|
||||
</span>
|
||||
|
||||
<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>
|
||||
|
||||
<span id="go">
|
||||
<input type="image" name="search" src="../../../more/space.gif" alt="Search" id="search-button" />
|
||||
</span>
|
||||
|
||||
<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>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
Welcome to version 2 of <b>Boost.Python</b>, a C++ library which enables
|
||||
seamless interoperability between C++ and the <a href=
|
||||
"http://www.python.org">Python</a> programming language. The new version
|
||||
has been rewritten from the ground up, with a more convenient and
|
||||
flexible interface, and many new capabilities, including support for:
|
||||
|
||||
<ul>
|
||||
<li>References and Pointers</li>
|
||||
|
||||
<li>Globally Registered Type Coercions</li>
|
||||
|
||||
<li>Automatic Cross-Module Type Conversions</li>
|
||||
|
||||
<li>Efficient Function Overloading</li>
|
||||
|
||||
<li>C++ to Python Exception Translation</li>
|
||||
|
||||
<li>Default Arguments</li>
|
||||
|
||||
<li>Keyword Arguments</li>
|
||||
|
||||
<li>Manipulating Python objects in C++</li>
|
||||
|
||||
<li>Exporting C++ Iterators as Python Iterators</li>
|
||||
|
||||
<li>Documentation Strings</li>
|
||||
</ul>
|
||||
The development of these features was funded in part by grants to <a
|
||||
href="http://www.boost-consulting.com">Boost Consulting</a> from the <a
|
||||
href="http://www.llnl.gov/">Lawrence Livermore National Laboratories</a>
|
||||
and by the <a href="http://cci.lbl.gov/">Computational Crystallography
|
||||
Initiative</a> at Lawrence Berkeley National Laboratories.
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl class="index">
|
||||
@@ -35,30 +124,61 @@
|
||||
|
||||
<dt><a href="building.html">Building and Testing</a></dt>
|
||||
|
||||
<dt><a href="v2/reference.html">Reference</a></dt>
|
||||
<dt><a href="v2/reference.html">Reference Manual</a></dt>
|
||||
|
||||
<dt>Suites:</dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li><a href="v2/pickle.html">Pickle</a></li>
|
||||
<li><a href="v2/indexing.html">Indexing</a></li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
<dt><a href="v2/configuration.html">Configuration Information</a></dt>
|
||||
|
||||
<dt><a href="v2/rationale.html">Rationale</a></dt>
|
||||
<dt><a href="v2/platforms.html">Known Working Platforms and
|
||||
Compilers</a></dt>
|
||||
|
||||
<dt><a href="v2/definitions.html">Definitions</a></dt>
|
||||
|
||||
<dt><a href="v2/faq.html">Frequently Asked Questions (FAQs)</a></dt>
|
||||
<dt><a href="projects.html">Projects using Boost.Python</a></dt>
|
||||
|
||||
<dt><a href="v2/progress_reports.html">Progress Reports</a></dt>
|
||||
<dt><a href="support.html">Support Resources</a></dt>
|
||||
|
||||
<dt><a href="v2/faq.html">Frequently Asked Questions (FAQs)</a></dt>
|
||||
|
||||
<dt><a href="http://www.language-binding.net/pyplusplus/pyplusplus.html">Py++ Boost.Python code generator</a></dt>
|
||||
|
||||
<dt><a href="../pyste/index.html">Pyste Boost.Python code generator (no longer maintained)</a></dt>
|
||||
|
||||
<dt><a href="internals.html">Internals Documentation</a></dt>
|
||||
|
||||
<dt><a href="news.html">News/Change Log</a></dt>
|
||||
|
||||
<dt><a href="../todo.html">TODO list</a></dt>
|
||||
|
||||
<dt><a href="v2/progress_reports.html">LLNL Progress Reports</a></dt>
|
||||
|
||||
<dt><a href="v2/acknowledgments.html">Acknowledgments</a></dt>
|
||||
</dl>
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<h2>Articles</h2>
|
||||
|
||||
"<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 -->
|
||||
08 October, 2002
|
||||
26 August, 2003
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href="../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i></p>
|
||||
<p><i>© Copyright <a href="../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002-2003.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
186
doc/internals.html
Executable 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
Executable 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.
|
||||
|
||||
@@ -1,326 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<title>A New Type Conversion Mechanism for Boost.Python</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<p><img border="0" src="../../../c++boost.gif" width="277" height="86"
|
||||
alt="boost logo"></p>
|
||||
|
||||
<h1>A New Type Conversion Mechanism for Boost.Python</h1>
|
||||
|
||||
<p>By <a href="../../../people/dave_abrahams.htm">David Abrahams</a>.
|
||||
|
||||
<h2>Introduction</h2>
|
||||
|
||||
This document describes a redesign of the mechanism for automatically
|
||||
converting objects between C++ and Python. The current implementation
|
||||
uses two functions for any type <tt>T</tt>:
|
||||
|
||||
<blockquote><pre>
|
||||
U from_python(PyObject*, type<T>);
|
||||
void to_python(V);
|
||||
</pre></blockquote>
|
||||
|
||||
where U is convertible to T and T is convertible to V. These functions
|
||||
are at the heart of C++/Python interoperability in Boost.Python, so
|
||||
why would we want to change them? There are many reasons:
|
||||
|
||||
<h3>Bugs</h3>
|
||||
<p>Firstly, the current mechanism relies on a common C++ compiler
|
||||
bug. This is not just embarrassing: as compilers get to be more
|
||||
conformant, the library stops working. The issue, in detail, is the
|
||||
use of inline friend functions in templates to generate
|
||||
conversions. It is a very powerful, and legal technique as long as
|
||||
it's used correctly:
|
||||
|
||||
<blockquote><pre>
|
||||
template <class Derived>
|
||||
struct add_some_functions
|
||||
{
|
||||
friend <i>return-type</i> some_function1(..., Derived <i>cv-*-&-opt</i>, ...);
|
||||
friend <i>return-type</i> some_function2(..., Derived <i>cv-*-&-opt</i>, ...);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct some_template : add_some_functions<some_template<T> >
|
||||
{
|
||||
};
|
||||
</pre></blockquote>
|
||||
|
||||
The <tt>add_some_functions</tt> template generates free functions
|
||||
which operate on <tt>Derived</tt>, or on related types. Strictly
|
||||
speaking the related types are not just cv-qualified <tt>Derived</tt>
|
||||
values, pointers and/or references. Section 3.4.2 in the standard
|
||||
describes exactly which types you must use as parameters to these
|
||||
functions if you want the functions to be found
|
||||
(there is also a less-technical description in section 11.5.1 of
|
||||
C++PL3 <a href="#ref_1">[1]</a>). Suffice it to say that
|
||||
with the current design, the <tt>from_python</tt> and
|
||||
<tt>to_python</tt> functions are not supposed to be callable under any
|
||||
conditions!
|
||||
|
||||
<h3>Compilation and Linking Time</h3>
|
||||
|
||||
The conversion functions generated for each wrapped class using the
|
||||
above technique are not function templates, but regular functions. The
|
||||
upshot is that they must <i>all</i> be generated regardless of whether
|
||||
they are actually used. Generating all of those functions can slow
|
||||
down module compilation, and resolving the references can slow down
|
||||
linking.
|
||||
|
||||
<h3>Efficiency</h3>
|
||||
|
||||
The conversion functions are primarily used in (member) function
|
||||
wrappers to convert the arguments and return values. Being functions,
|
||||
converters have no interface which allows us to ask "will the
|
||||
conversion succeed?" without calling the function. Since the
|
||||
return value of the function must be the object to be passed as an
|
||||
argument, Boost.Python currently uses C++ exception-handling to detect
|
||||
an unsuccessful conversion. It's not a particularly good use of
|
||||
exception-handling, since the failure is not handled very far from
|
||||
where it occurred. More importantly, it means that C++ exceptions are
|
||||
thrown during overload resolution as we seek an overload that matches
|
||||
the arguments passed. Depending on the implementation, this approach
|
||||
can result in significant slowdowns.
|
||||
|
||||
<p>It is also unclear that the current library generates a minimal
|
||||
amount of code for any type conversion. Many of the conversion
|
||||
functions are nontrivial, and partly because of compiler limitations,
|
||||
they are declared <tt>inline</tt>. Also, we could have done a better
|
||||
job separating the type-specific conversion code from the code which
|
||||
is type-independent.
|
||||
|
||||
<h3>Cross-module Support</h3>
|
||||
|
||||
The current strategy requires every module to contain the definition
|
||||
of conversions it uses. In general, a new module can never supply
|
||||
conversion code which is used by another module. Ralf Grosse-Kunstleve
|
||||
designed a clever system which imports conversions directly from one
|
||||
library into another using some explicit declarations, but it has some
|
||||
disadvantages also:
|
||||
|
||||
<ol>
|
||||
<li>The system Ullrich Koethe designed for implicit conversion between
|
||||
wrapped classes related through inheritance does not currently work if
|
||||
the classes are defined in separate modules.
|
||||
|
||||
<li>The writer of the importing module is required to know the name of
|
||||
the module supplying the imported conversions.
|
||||
|
||||
<li>There can be only one way to extract any given C++ type from a
|
||||
Python object in a given module.
|
||||
</ol>
|
||||
|
||||
The first item might be addressed by moving Boost.Python into a shared
|
||||
library, but the other two cannot. Ralf turned the limitation in item
|
||||
two into a feature: the required module is loaded implicitly when a
|
||||
conversion it defines is invoked. We will probably want to provide
|
||||
that functionality anyway, but it's not clear that we should require
|
||||
the declaration of all such conversions. The final item is a more
|
||||
serious limitation. If, for example, new numeric types are defined in
|
||||
separate modules, and these types can all be converted to
|
||||
<tt>double</tt>s, we have to choose just one conversion method.
|
||||
|
||||
<h3>Ease-of-use</h3>
|
||||
|
||||
One persistent source of confusion for users of Boost.Python has been
|
||||
the fact that conversions for a class are not be visible at
|
||||
compile-time until the declaration of that class has been seen. When
|
||||
the user tries to expose a (member) function operating on or returning
|
||||
an instance of the class in question, compilation fails...even though
|
||||
the user goes on to expose the class in the same translation unit!
|
||||
|
||||
<p>
|
||||
The new system lifts all compile-time checks for the existence of
|
||||
particular type conversions and replaces them with runtime checks, in
|
||||
true Pythonic style. While this might seem cavalier, the compile-time
|
||||
checks are actually not much use in the current system if many classes
|
||||
are wrapped in separate modules, since the checks are based only on
|
||||
the user's declaration that the conversions exist.
|
||||
|
||||
<h2>The New Design</h2>
|
||||
|
||||
<h3>Motivation</h3>
|
||||
|
||||
The new design was heavily influenced by a desire to generate as
|
||||
little code as possible in extension modules. Some of Boost.Python's
|
||||
clients are enormous projects where link time is proportional to the
|
||||
amount of object code, and there are many Python extension modules. As
|
||||
such, we try to keep type-specific conversion code out of modules
|
||||
other than the one the converters are defined in, and rely as much as
|
||||
possible on centralized control through a shared library.
|
||||
|
||||
<h3>The Basics</h3>
|
||||
|
||||
The library contains a <tt>registry</tt> which maps runtime type
|
||||
identifiers (actually an extension of <tt>std::type_info</tt> which
|
||||
preserves references and constness) to entries containing type
|
||||
converters. An <tt>entry</tt> can contain only one converter from C++ to Python
|
||||
(<tt>wrapper</tt>), but many converters from Python to C++
|
||||
(<tt>unwrapper</tt>s). <font color="#ff0000">What should happen if
|
||||
multiple modules try to register wrappers for the same type?</font>. Wrappers
|
||||
and unwrappers are known as <tt>body</tt> objects, and are accessed
|
||||
by the user and the library (in its function-wrapping code) through
|
||||
corresponding <tt>handle</tt> (<tt>wrap<T></tt> and
|
||||
<tt>unwrap<T></tt>) objects. The <tt>handle</tt> objects are
|
||||
extremely lightweight, and delegate <i>all</i> of their operations to
|
||||
the corresponding <tt>body</tt>.
|
||||
|
||||
<p>
|
||||
When a <tt>handle</tt> object is constructed, it accesses the
|
||||
registry to find a corresponding <tt>body</tt> that can convert the
|
||||
handle's constructor argument. Actually the registry record for any
|
||||
type
|
||||
<tt>T</tt>used in a module is looked up only once and stored in a
|
||||
static <tt>registration<T></tt> object for efficiency. For
|
||||
example, if the handle is an <tt>unwrap<Foo&></tt> object,
|
||||
the <tt>entry</tt> for <tt>Foo&</tt> is looked up in the
|
||||
<tt>registry</tt>, and each <tt>unwrapper</tt> it contains is queried
|
||||
to determine if it can convert the
|
||||
<tt>PyObject*</tt> with which the <tt>unwrap</tt> was constructed. If
|
||||
a body object which can perform the conversion is found, a pointer to
|
||||
it is stored in the handle. A body object may at any point store
|
||||
additional data in the handle to speed up the conversion process.
|
||||
|
||||
<p>
|
||||
Now that the handle has been constructed, the user can ask it whether
|
||||
the conversion can be performed. All handles can be tested as though
|
||||
they were convertible to <tt>bool</tt>; a <tt>true</tt> value
|
||||
indicates success. If the user forges ahead and tries to do the
|
||||
conversion without checking when no conversion is possible, an
|
||||
exception will be thrown as usual. The conversion itself is performed
|
||||
by the body object.
|
||||
|
||||
<h3>Handling complex conversions</h3>
|
||||
|
||||
<p>Some conversions may require a dynamic allocation. For example,
|
||||
when a Python tuple is converted to a <tt>std::vector<double>
|
||||
const&</tt>, we need some storage into which to construct the
|
||||
vector so that a reference to it can be formed. Furthermore, multiple
|
||||
conversions of the same type may need to be "active"
|
||||
simultaneously, so we can't keep a single copy of the storage
|
||||
anywhere. We could keep the storage in the <tt>body</tt> object, and
|
||||
have the body clone itself in case the storage is used, but in that
|
||||
case the storage in the body which lives in the registry is never
|
||||
used. If the storage was actually an object of the target type (the
|
||||
safest way in C++), we'd have to find a way to construct one for the
|
||||
body in the registry, since it may not have a default constructor.
|
||||
|
||||
<p>
|
||||
The most obvious way out of this quagmire is to allocate the object using a
|
||||
<i>new-expression</i>, and store a pointer to it in the handle. Since
|
||||
the <tt>body</tt> object knows everything about the data it needs to
|
||||
allocate (if any), it is also given responsibility for destroying that
|
||||
data. When the <tt>handle</tt> is destroyed it asks the <tt>body</tt>
|
||||
object to tear down any data it may have stored there. In many ways,
|
||||
you can think of the <tt>body</tt> as a "dynamically-determined
|
||||
vtable" for the handle.
|
||||
|
||||
<h3>Eliminating Redundancy</h3>
|
||||
|
||||
If you look at the current Boost.Python code, you'll see that there
|
||||
are an enormous number of conversion functions generated for each
|
||||
wrapped class. For a given class <tt>T</tt>, functions are generated
|
||||
to extract the following types <tt>from_python</tt>:
|
||||
|
||||
<blockquote><pre>
|
||||
T*
|
||||
T const*
|
||||
T const* const&
|
||||
T* const&
|
||||
T&
|
||||
T const&
|
||||
T
|
||||
std::auto_ptr<T>&
|
||||
std::auto_ptr<T>
|
||||
std::auto_ptr<T> const&
|
||||
boost::shared_ptr<T>&
|
||||
boost::shared_ptr<T>
|
||||
boost::shared_ptr<T> const&
|
||||
</pre></blockquote>
|
||||
|
||||
Most of these are implemented in terms of just a few conversions, and
|
||||
<t>if you're lucky</t>, they will be inlined and cause no extra
|
||||
overhead. In the new system, however, a significant amount of data
|
||||
will be associated with each type that needs to be converted. We
|
||||
certainly don't want to register a separate unwrapper object for all
|
||||
of the above types.
|
||||
|
||||
<p>Fortunately, much of the redundancy can be eliminated. For example,
|
||||
if we generate an unwrapper for <tt>T&</tt>, we don't need an
|
||||
unwrapper for <tt>T const&</tt> or <tt>T</tt>. Accordingly, the user's
|
||||
request to wrap/unwrap a given type is translated at compile-time into
|
||||
a request which helps to eliminate redundancy. The rules used to
|
||||
<tt>unwrap</tt> a type are:
|
||||
|
||||
<ol>
|
||||
<li> Treat built-in types specially: when unwrapping a value or
|
||||
constant reference to one of these, use a value for the target
|
||||
type. It will bind to a const reference if neccessary, and more
|
||||
importantly, avoids having to dynamically allocate room for
|
||||
an lvalue of types which can be cheaply copied.
|
||||
<li>
|
||||
Reduce everything else to a reference to an un-cv-qualified type
|
||||
where possible. Since cv-qualification is lost on Python
|
||||
anyway, there's no point in trying to convert to a
|
||||
<tt>const&</tt>. <font color="#ff0000">What about conversions
|
||||
to values like the tuple->vector example above? It seems to me
|
||||
that we don't want to make a <tt>vector<double>&</tt>
|
||||
(non-const) converter available for that case. We may need to
|
||||
rethink this slightly.</font>
|
||||
</ol>
|
||||
|
||||
<p>To handle the problem described above in item 2, we modify the
|
||||
procedure slightly. To unwrap any non-scalar <tt>T</tt>, we seek an
|
||||
unwrapper for <tt>add_reference<T>::type</tt>. Unwrappers for
|
||||
<tt>T const&</tt> always return <tt>T&</tt>, and are
|
||||
registered under both <tt>T &</tt> and
|
||||
<tt>T const&</tt>.
|
||||
|
||||
<p>For compilers not supporting partial specialization, unwrappers for
|
||||
<tt>T const&</tt> must return <tt>T const&</tt>
|
||||
(since constness can't be stripped), but a separate unwrapper object
|
||||
need to be registered for <tt>T &</tt> and
|
||||
<tt>T const&</tt> anyway, for the same reasons.
|
||||
|
||||
<font color="#ff0000">We may want to make it possible to compile as
|
||||
though partial specialization were unavailable even on compilers where
|
||||
it is available, in case modules could be compiled by different
|
||||
compilers with compatible ABIs (e.g. Intel C++ and MSVC6).</font>
|
||||
|
||||
<h3>Efficient Argument Conversion</h3>
|
||||
|
||||
Since type conversions are primarily used in function wrappers, an
|
||||
optimization is provided for the case where a group of conversions are
|
||||
used together. Each <tt>handle</tt> class has a corresponding
|
||||
"<tt>_more</tt>" class which does the same job, but has a
|
||||
trivial destructor. Instead of asking each "<tt>_more</tt>"
|
||||
handle to destroy its own body, it is linked into an endogenous list
|
||||
managed by the first (ordinary) handle. The <tt>wrap</tt> and
|
||||
<tt>unwrap</tt> destructors are responsible for traversing that list
|
||||
and asking each <tt>body</tt> class to tear down its
|
||||
<tt>handle</tt>. This mechanism is also used to determine if all of
|
||||
the argument/return-value conversions can succeed with a single
|
||||
function call in the function wrapping code. <font color="#ff0000">We
|
||||
might need to handle return values in a separate step for Python
|
||||
callbacks, since the availablility of a conversion won't be known
|
||||
until the result object is retrieved.</font>
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
<h2>References</h2>
|
||||
|
||||
<p><a name="ref_1">[1]</a>B. Stroustrup, The C++ Programming Language
|
||||
Special Edition Addison-Wesley, ISBN 0-201-70073-5.
|
||||
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->19 December 2001<!--webbot bot="Timestamp" endspan i-checksum="31283" --></p>
|
||||
<p>© Copyright David Abrahams, 2001</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,111 +0,0 @@
|
||||
This hierarchy contains converter handle classes.
|
||||
|
||||
|
||||
+-------------+
|
||||
| noncopyable |
|
||||
+-------------+
|
||||
^
|
||||
| A common base class used so that
|
||||
+--------+--------+ conversions can be linked into a
|
||||
| conversion_base | chain for efficient argument
|
||||
+-----------------+ conversion
|
||||
^
|
||||
|
|
||||
+---------+-----------+
|
||||
| |
|
||||
+-----------+----+ +------+-------+ only used for
|
||||
| unwrap_more<T> | | wrap_more<T> | chaining, and don't manage any
|
||||
+----------------+ +--------------+ resources.
|
||||
^ ^
|
||||
| |
|
||||
+-----+-----+ +-------+-+ These converters are what users
|
||||
| unwrap<T> | | wrap<T> | actually touch, but they do so
|
||||
+-----------+ +---------+ through a type generator which
|
||||
minimizes the number of converters
|
||||
that must be generated, so they
|
||||
|
||||
|
||||
Each unwrap<T>, unwrap_more<T>, wrap<T>, wrap_more<T> converter holds
|
||||
a reference to an appropriate converter object
|
||||
|
||||
This hierarchy contains converter body classes
|
||||
|
||||
Exposes use/release which
|
||||
are needed in case the converter
|
||||
+-----------+ in the registry needs to be
|
||||
| converter | cloned. That occurs when a
|
||||
+-----------+ unwrap target type is not
|
||||
^ contained within the Python object.
|
||||
|
|
||||
+------------------+-----+
|
||||
| |
|
||||
+--------+-------+ Exposes |
|
||||
| unwrapper_base | convertible() |
|
||||
+----------------+ |
|
||||
^ |
|
||||
| |
|
||||
+--------+----+ +-----+-----+
|
||||
| unwrapper<T>| | wrapper<T>|
|
||||
+-------------+ +-----------+
|
||||
Exposes T convert(PyObject*) Exposes PyObject* convert(T)
|
||||
|
||||
|
||||
unwrap:
|
||||
|
||||
constructed with a PyObject*, whose reference count is
|
||||
incremented.
|
||||
|
||||
find the registry entry for the target type
|
||||
|
||||
look in the collection of converters for one which claims to be
|
||||
able to convert the PyObject to the target type.
|
||||
|
||||
stick a pointer to the unwrapper in the unwrap object
|
||||
|
||||
when unwrap is queried for convertibility, it checks to see
|
||||
if it has a pointer to an unwrapper.
|
||||
|
||||
on conversion, the unwrapper is asked to allocate an
|
||||
implementation if the unwrap object isn't already holding
|
||||
one. The unwrap object "takes ownership" of the unwrapper's
|
||||
implementation. No memory allocation will actually take place
|
||||
unless this is a value conversion.
|
||||
|
||||
on destruction, the unwrapper is asked to free any implementation
|
||||
held by the unwrap object. No memory deallocation actually
|
||||
takes place unless this is a value conversion
|
||||
|
||||
on destruction, the reference count on the held PyObject is
|
||||
decremented.
|
||||
|
||||
We need to make sure that by default, you can't instantiate
|
||||
callback<> for reference and pointer return types: although the
|
||||
unwrappers may exist, they may convert by-value, which would cause
|
||||
the referent to be destroyed upon return.
|
||||
|
||||
wrap:
|
||||
|
||||
find the registry entry for the source type
|
||||
|
||||
see if there is a converter. If found, stick a pointer to it in
|
||||
the wrap object.
|
||||
|
||||
when queried for convertibility, it checks to see if it has a
|
||||
pointer to a converter.
|
||||
|
||||
on conversion, a reference to the target PyObject is held by the
|
||||
converter. Generally, the PyObject will have been created by the
|
||||
converter, but in certain cases it may be a pre-existing object,
|
||||
whose reference count will have been incremented.
|
||||
|
||||
when a wrap<T> x is used to return from a C++ function,
|
||||
x.release() is returned so that x no longer holds a reference to
|
||||
the PyObject when destroyed.
|
||||
|
||||
Otherwise, on destruction, any PyObject still held has its
|
||||
reference-count decremented.
|
||||
|
||||
|
||||
When a converter is created by the user, the appropriate element must
|
||||
be added to the registry; when it is destroyed, it must be removed
|
||||
from the registry.
|
||||
299
doc/news.html
Normal file
@@ -0,0 +1,299 @@
|
||||
<!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 CVS</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="../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002-2003.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
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?
|
||||
|
||||
|
||||
445
doc/projects.html
Normal file
@@ -0,0 +1,445 @@
|
||||
<!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://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 -->
|
||||
15 July, 2003</p>
|
||||
|
||||
<p><i>© Copyright <a href="../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002-2003.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
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="../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2003.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
15
doc/tutorial/doc/Jamfile.v2
Normal file
@@ -0,0 +1,15 @@
|
||||
# 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 ;
|
||||
|
||||
boostbook tutorial
|
||||
:
|
||||
tutorial.qbk
|
||||
:
|
||||
<xsl:param>boost.root=../../../../../..
|
||||
<xsl:param>boost.libraries=../../../../../../libs/libraries.htm
|
||||
;
|
||||
@@ -1,77 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Basic Interface</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="object_interface.html">
|
||||
<link rel="next" href="derived_object_types.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Basic Interface</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="object_interface.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="derived_object_types.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
Class <tt>object</tt> wraps <tt>PyObject*</tt>. All the intricacies of dealing with
|
||||
<tt>PyObject</tt>s such as managing reference counting are handled by the
|
||||
<tt>object</tt> class. C++ object interoperability is seamless. Boost.Python C++
|
||||
<tt>object</tt>s can in fact be explicitly constructed from any C++ object.</p>
|
||||
<p>
|
||||
To illustrate, this Python code snippet:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>def </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>x</span><span class=special>, </span><span class=identifier>y</span><span class=special>):
|
||||
</span><span class=keyword>if </span><span class=special>(</span><span class=identifier>y </span><span class=special>== </span><span class=literal>'foo'</span><span class=special>):
|
||||
</span><span class=identifier>x</span><span class=special>[</span><span class=number>3</span><span class=special>:</span><span class=number>7</span><span class=special>] </span><span class=special>= </span><span class=literal>'bar'
|
||||
</span><span class=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=identifier>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></code>
|
||||
<p>
|
||||
Can be rewritten in C++ using Boost.Python facilities this way:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>object </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>object </span><span class=identifier>x</span><span class=special>, </span><span class=identifier>object </span><span class=identifier>y</span><span class=special>) </span><span class=special>{
|
||||
</span><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></code>
|
||||
<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>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="object_interface.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="derived_object_types.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,186 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Building an Extension Module </title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="class_data_members.html">
|
||||
<link rel="next" href="inheritance.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><strong>Building
|
||||
an Extension Module</strong></font> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><img src="theme/l_arr.gif" border="0"></td>
|
||||
<td width="20"><img src="theme/r_arr.gif" border="0"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2>Building Boost.Python</h2>
|
||||
<p>Every Boost.Python extension module must be linked with the boost_python shared
|
||||
library. To build boost_python, use <a href="file:///C:/dev/boost/tools/build/index.html">Boost.Build</a>
|
||||
in the usual way from the <tt>libs/python/build</tt> subdirectory of your boost
|
||||
installation (if you have already built boost from the top level this may have
|
||||
no effect, since the work is already done).</p>
|
||||
<h2>Configuration</h2>
|
||||
<p>You may need to configure the following variables to point Boost.Build at your
|
||||
Python installation:</p>
|
||||
<table width="95%" border="0" align="center">
|
||||
<tr class="table_title">
|
||||
<td width="24%">Variable Name</td>
|
||||
<td width="20%">Semantics</td>
|
||||
<td width="21%">Default</td>
|
||||
<td width="35%">Notes</td>
|
||||
</tr>
|
||||
<tr class="table_cells">
|
||||
<td><tt>PYTHON_ROOT</tt></td>
|
||||
<td> The root directory of your Python installation</td>
|
||||
<td>Windows: <tt><br>
|
||||
c:/tools/python <br>
|
||||
Unix: /usr/local</tt></td>
|
||||
<td>On Unix, this is the <tt>--with-prefix=</tt> directory used to configure
|
||||
Python</td>
|
||||
</tr>
|
||||
<tr class="table_cells">
|
||||
<td><tt>PYTHON_VERSION</tt></td>
|
||||
<td> The The 2-part python Major.Minor version number</td>
|
||||
<td>Windows: 2.1 Unix: 1.5</td>
|
||||
<td>Be sure not to include a third number, e.g. not "2.2.1", even
|
||||
if that's the version you have.</td>
|
||||
</tr>
|
||||
<tr class="table_cells">
|
||||
<td><tt>PYTHON_INCLUDES</tt></td>
|
||||
<td> path to Python <span class="preprocessor">#include</span> directories</td>
|
||||
<td>Autoconfigured from <tt><br>
|
||||
PYTHON_ROOT</tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr class="table_cells">
|
||||
<td><tt>PYTHON_LIB_PATH</tt></td>
|
||||
<td>path to Python library object.</td>
|
||||
<td>Autoconfigured from <tt><br>
|
||||
PYTHON_ROOT</tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr class="table_cells">
|
||||
<td><tt>PYTHON_STDLIB_PATH</tt></td>
|
||||
<td>path to Python standard library modules</td>
|
||||
<td>Autoconfigured from <tt><br>
|
||||
PYTHON_ROOT</tt></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr class="table_cells">
|
||||
<td height="129"><tt>CYGWIN_ROOT</tt></td>
|
||||
<td> path to the user's Cygwin installation</td>
|
||||
<td>Autoconfigured from <tt><br>
|
||||
PYTHON_ROOT</tt></td>
|
||||
<td><a href="http://www.cygwin.com">Cygwin</a> only. This and the following
|
||||
two settings are useful when building with multiple toolsets on Windows,
|
||||
since Cygwin requires a different build of Python.</td>
|
||||
</tr>
|
||||
<tr class="table_cells">
|
||||
<td height="21"><tt>GCC_PYTHON_ROOT</tt></td>
|
||||
<td>path to the user's Cygwin Python installation</td>
|
||||
<td><tt>$(CYGWIN_ROOT)<br>
|
||||
/usr/local</tt></td>
|
||||
<td> <a href="http://www.cygwin.com">Cygwin</a> only</td>
|
||||
</tr>
|
||||
<tr class="table_cells">
|
||||
<td><tt>GCC_DEBUG_PYTHON_ROOT</tt></td>
|
||||
<td> path to the user's Cygwin <a href="#variants">pydebug</a>
|
||||
build</td>
|
||||
<td><tt>$(CYGWIN_ROOT)<br>
|
||||
/usr/local/pydebug</tt></td>
|
||||
<td> <a href="http://www.cygwin.com">Cygwin</a> only</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2>Results</h2>
|
||||
<p>The build process will create a <tt>libs/python/build/bin-stage</tt> subdirectory
|
||||
of the boost root (or of <tt>$(ALL_LOCATE_TARGET)</tt>, if you have set that
|
||||
variable), containing the built libraries. The libraries are actually built
|
||||
to unique directories for each toolset and variant elsewhere in the filesystem,
|
||||
and copied to the bin-stage directory as a convenience, so if you build with
|
||||
multiple toolsets at once, the product of later toolsets will overwrite that
|
||||
of earlier toolsets in bin-stage.</p>
|
||||
<h2>Testing</h2>
|
||||
<p>To build and test Boost.Python from within the <tt>libs/python/build directory</tt>,
|
||||
invoke</p>
|
||||
<pre> bjam -sTOOLS=<a href="../../../tools/build/index.html">toolset</a> test</pre>
|
||||
<p>This will update all of the Boost.Python v1 test and example targets. The tests
|
||||
are relatively quiet by default. To get more-verbose output, you might try</p>
|
||||
<pre> bjam -sTOOLS=<a href="../../../tools/build/index.html">toolset</a> -sPYTHON_TEST_ARGS=-v test</pre>
|
||||
<p>which will print each test's Python code with the expected output as it passes.</p>
|
||||
<h2>Building your Extension Module</h2>
|
||||
<p>Though there are other approaches, the easiest way to build an extension module
|
||||
using Boost.Python is with Boost.Build. Until Boost.Build v2 is released, cross-project
|
||||
build dependencies are not supported, so it works most smoothly if you add a
|
||||
new subproject to your boost installation. The <tt>libs/python/example</tt>
|
||||
subdirectory of your boost installation contains a minimal example (along with
|
||||
many extra sources). To copy the example subproject:</p>
|
||||
<ol>
|
||||
<li> Create a new subdirectory in,<tt> libs/python</tt>, say <tt>libs/python/my_project</tt>.</li>
|
||||
<li> Copy <a href="../example/Jamfile"><tt>libs/python/example/Jamfile</tt></a>
|
||||
to your new directory.</li>
|
||||
<li> Edit the Jamfile as appropriate for your project. You'll want to change
|
||||
the <tt>subproject</tt> rule invocation at the top, and the names of some
|
||||
of the source files and/or targets.</li>
|
||||
</ol>
|
||||
<p>If you can't modify or copy your boost installation, the alternative is to
|
||||
create your own Boost.Build project. A similar example you can use as a starting
|
||||
point is available in <a href="../example/project.zip">this archive</a>. You'll
|
||||
need to edit the Jamfile and Jamrules files, depending on the relative location
|
||||
of your Boost installation and the new project. Note that automatic testing
|
||||
of extension modules is not available in this configuration.</p>
|
||||
<h2>Build Variants</h2>
|
||||
<p>Three variant configurations of all python-related targets are supported, and
|
||||
can be selected by setting the BUILD variable:</p>
|
||||
<p> * <tt>release</tt> (optimization, <tt>-DNDEBUG</tt>)<br>
|
||||
* <tt>debug</tt> (no optimization <tt>-D_DEBUG</tt>)<br>
|
||||
* <tt>debug-python</tt> (no optimization, <tt>-D_DEBUG -DBOOST_DEBUG_PYTHON</tt>)</p>
|
||||
<p>The first two variants of the boost_python library are built by default, and
|
||||
are compatible with the default Python distribution. The debug-python variant
|
||||
corresponds to a specially-built debugging version of Python. On Unix platforms,
|
||||
this python is built by adding <tt>--with-pydebug</tt> when configuring the
|
||||
Python build. On Windows, the debugging version of Python is generated by the
|
||||
"Win32 Debug" target of the PCBuild.dsw Visual C++ 6.0 project in
|
||||
the PCBuild subdirectory of your Python distribution. Extension modules built
|
||||
with Python debugging enabled are not link-compatible with a non-debug build
|
||||
of Python. Since few people actually have a debug build of Python (it doesn't
|
||||
come with the standard distribution), the normal debug variant builds modules
|
||||
which are compatible with ordinary Python.</p>
|
||||
<p>On many windows compilers, when extension modules are built with <tt>-D_DEBUG</tt>,
|
||||
Python defaults to force linking with a special debugging version of the Python
|
||||
DLL. Since this debug DLL isn't supplied with the default Python installation
|
||||
for Windows, Boost.Python uses <a href="../../../boost/python/detail/wrap_python.hpp"><tt>boost/python/detail/wrap_python.hpp</tt></a>
|
||||
to temporarily undefine <tt>_DEBUG</tt> when <tt>Python.h</tt> is <span class="preprocessor">#included</span>
|
||||
- unless <tt>BOOST_DEBUG_PYTHON</tt> is defined.</p>
|
||||
<p>If you want the extra runtime checks available with the debugging version of
|
||||
the library, <span class="preprocessor">#define</span> <tt>BOOST_DEBUG_PYTHON</tt>
|
||||
to re-enable python debuggin, and link with the debug-python variant of boost_python.</p>
|
||||
<p>If you do not <span class="preprocessor">#define</span> <tt>BOOST_DEBUG_PYTHON</tt>,
|
||||
be sure that any source files in your extension module <span class="preprocessor">#include</span>
|
||||
<tt><boost/python/detail/wrap_python.hpp></tt> instead of the usual <tt>Python.h</tt>,
|
||||
or you will have link incompatibilities.</p>
|
||||
<code></code>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><img src="theme/l_arr.gif" border="0"></td>
|
||||
<td width="20"><img src="theme/r_arr.gif" border="0"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,191 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Building Hello World</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="quickstart.html">
|
||||
<link rel="next" href="exposing_classes.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Building Hello World</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="quickstart.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="exposing_classes.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<a name="from_start_to_finish"></a><h2>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 shall outline the steps
|
||||
necessary to achieve that. We shall use the build tool that comes bundled
|
||||
with every boost distribution: <b>bjam</b>.</p>
|
||||
<table width="80%" border="0" align="center">
|
||||
<tr>
|
||||
<td class="note_box">
|
||||
<img src="theme/lens.gif"></img> <b>Building without bjam</b><br><br>
|
||||
|
||||
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>bjam</tt>.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
We shall 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">
|
||||
building.html</a>.
|
||||
After this brief <i>bjam</i> tutorial, we should have built two DLLs:</p>
|
||||
<ul><li>boost_python.dll</li><li>hello.pyd</li></ul><p>
|
||||
if you are on Windows, and</p>
|
||||
<ul><li>libboost_python.so</li><li>hello.so</li></ul><p>
|
||||
if you are on Unix.</p>
|
||||
<p>
|
||||
The tutorial example can be found in the directory:
|
||||
<tt>libs/python/example/tutorial</tt>. There, you can find:</p>
|
||||
<ul><li>hello.cpp</li><li>Jamfile</li></ul><p>
|
||||
The <tt>hello.cpp</tt> file is our C++ hello world example. The <tt>Jamfile</tt> is a
|
||||
minimalist <i>bjam</i> script that builds the DLLs for us.</p>
|
||||
<p>
|
||||
Before anything else, you should have the bjam executable in your boost
|
||||
directory or somewhere in your path such that <tt>bjam</tt> can be executed in
|
||||
the command line. Pre-built Boost.Jam executables are available for most
|
||||
platforms. For example, a pre-built Microsoft Windows bjam executable can
|
||||
be downloaded <a href="http://boost.sourceforge.net/jam-executables/bin.ntx86/bjam.zip">
|
||||
here</a>.
|
||||
The complete list of bjam pre-built
|
||||
executables can be found <a href="../../../../../tools/build/index.html#Jam">
|
||||
here</a>.</p>
|
||||
<a name="lets_jam_"></a><h2>Lets Jam!</h2><p>
|
||||
<img src="theme/jam.png"></img></p>
|
||||
<p>
|
||||
Here is our minimalist Jamfile:</p>
|
||||
<code><pre>
|
||||
subproject libs/python/example/tutorial ;
|
||||
|
||||
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include python.jam ;
|
||||
|
||||
extension hello # Declare a Python extension called hello
|
||||
: hello.cpp # source
|
||||
<dll>../../build/boost_python # dependencies
|
||||
;
|
||||
</pre></code><p>
|
||||
First, we need to specify our location in the boost project hierarchy.
|
||||
It so happens that the tutorial example is located in <tt>/libs/python/example/tutorial</tt>.
|
||||
Thus:</p>
|
||||
<code><pre>
|
||||
subproject libs/python/example/tutorial ;
|
||||
</pre></code><p>
|
||||
Then we will include the definitions needed by Python modules:</p>
|
||||
<code><pre>
|
||||
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include python.jam ;
|
||||
</pre></code><p>
|
||||
Finally we declare our <tt>hello</tt> extension:</p>
|
||||
<code><pre>
|
||||
extension hello # Declare a Python extension called hello
|
||||
: hello.cpp # source
|
||||
<dll>../../build/boost_python # dependencies
|
||||
;
|
||||
</pre></code><a name="running_bjam"></a><h2>Running bjam</h2><p>
|
||||
<i>bjam</i> is run using your operating system's command line interpreter.</p>
|
||||
<blockquote><p>Start it up.</p></blockquote><p>
|
||||
Make sure that the environment is set so that we can invoke the C++
|
||||
compiler. With MSVC, that would mean running the <tt>Vcvars32.bat</tt> batch
|
||||
file. For instance:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>C</span><span class=special>:\</span><span class=identifier>Program </span><span class=identifier>Files</span><span class=special>\</span><span class=identifier>Microsoft </span><span class=identifier>Visual </span><span class=identifier>Studio</span><span class=special>\</span><span class=identifier>VC98</span><span class=special>\</span><span class=identifier>bin</span><span class=special>\</span><span class=identifier>Vcvars32</span><span class=special>.</span><span class=identifier>bat
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Some environment variables will have to be setup for proper building of our
|
||||
Python modules. Example:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>set </span><span class=identifier>PYTHON_ROOT</span><span class=special>=</span><span class=identifier>c</span><span class=special>:/</span><span class=identifier>dev</span><span class=special>/</span><span class=identifier>tools</span><span class=special>/</span><span class=identifier>python
|
||||
</span><span class=identifier>set </span><span class=identifier>PYTHON_VERSION</span><span class=special>=</span><span class=number>2.2
|
||||
</span></pre></code>
|
||||
<p>
|
||||
The above assumes that the Python installation is in <tt>c:/dev/tools/python</tt>
|
||||
and that we are using Python version 2.2. You'll have to tweak this path
|
||||
appropriately. <img src="theme/note.gif"></img> Be sure not to include a third number, e.g. <b>not</b> "2.2.1",
|
||||
even if that's the version you have.</p>
|
||||
<p>
|
||||
Now we are ready... Be sure to <tt>cd</tt> to <tt>libs/python/example/tutorial</tt>
|
||||
where the tutorial <tt>"hello.cpp"</tt> and the <tt>"Jamfile"</tt> is situated.</p>
|
||||
<p>
|
||||
Finally:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>bjam </span><span class=special>-</span><span class=identifier>sTOOLS</span><span class=special>=</span><span class=identifier>msvc
|
||||
</span></pre></code>
|
||||
<p>
|
||||
We are again assuming that we are using Microsoft Visual C++ version 6. If
|
||||
not, then you will have to specify the appropriate tool. See
|
||||
<a href="../../../../../tools/build/index.html">
|
||||
Building Boost Libraries</a> for
|
||||
further details.</p>
|
||||
<p>
|
||||
It should be building now:</p>
|
||||
<code><pre>
|
||||
cd C:\dev\boost\libs\python\example\tutorial
|
||||
bjam -sTOOLS=msvc
|
||||
...patience...
|
||||
...found 1703 targets...
|
||||
...updating 40 targets...
|
||||
</pre></code><p>
|
||||
And so on... Finally:</p>
|
||||
<code><pre>
|
||||
vc-C++ ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
|
||||
runtime-link-dynamic\hello.obj
|
||||
hello.cpp
|
||||
vc-Link ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\msvc\debug\
|
||||
runtime-link-dynamic\hello.pyd ..\..\..\..\libs\python\example\tutorial\bin\
|
||||
hello.pyd\msvc\debug\runtime-link-dynamic\hello.lib
|
||||
Creating library ..\..\..\..\libs\python\example\tutorial\bin\hello.pyd\
|
||||
msvc\debug\runtime-link-dynamic\hello.lib and object ..\..\..\..\libs\python\
|
||||
example\tutorial\bin\hello.pyd\msvc\debug\runtime-link-dynamic\hello.exp
|
||||
...updated 40 targets...
|
||||
</pre></code><p>
|
||||
If all is well, you should now have:</p>
|
||||
<ul><li>boost_python.dll</li><li>hello.pyd</li></ul><p>
|
||||
if you are on Windows, and</p>
|
||||
<ul><li>libboost_python.so</li><li>hello.so</li></ul><p>
|
||||
if you are on Unix.</p>
|
||||
<p>
|
||||
<tt>boost_python.dll</tt> can be found somewhere in <tt>libs\python\build\bin</tt>
|
||||
while <tt>hello.pyd</tt> can be found somewhere in
|
||||
<tt>libs\python\example\tutorial\bin</tt>. After a successful build, you can just
|
||||
link in these DLLs with the Python interpreter. In Windows for example, you
|
||||
can simply put these libraries inside the directory where the Python
|
||||
executable is.</p>
|
||||
<p>
|
||||
You may now fire up Python and run our hello module:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=identifier>import </span><span class=identifier>hello
|
||||
</span><span class=special>>>> </span><span class=identifier>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></code>
|
||||
<blockquote><p><b>There you go... Have fun!</b></p></blockquote><table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="quickstart.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="exposing_classes.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,169 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Call Policies</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="functions.html">
|
||||
<link rel="next" href="default_arguments.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Call Policies</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="default_arguments.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<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>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<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>
|
||||
<code><pre>
|
||||
<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=identifier>x </span><span class=identifier>refers </span><span class=identifier>to </span><span class=identifier>some </span><span class=identifier>C</span><span class=special>++ </span><span class=identifier>X
|
||||
</span><span class=special>>>> </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=identifier>CRASH</span><span class=special>!
|
||||
</span></pre></code>
|
||||
<p>
|
||||
What's the problem?</p>
|
||||
<p>
|
||||
Well, what if f() was implemented as shown below:</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<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>
|
||||
<ol><li><tt>f</tt> is called passing in a reference to <tt>y</tt> and a pointer to <tt>z</tt></li><li>A reference to <tt>y.x</tt> is returned</li><li><tt>y</tt> is deleted. <tt>x</tt> is a dangling reference</li><li><tt>x.some_method()</tt> is called</li><li><b>BOOM!</b></li></ol><p>
|
||||
We could copy result into a new object:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>y</span><span class=special>, </span><span class=identifier>z</span><span class=special>).</span><span class=identifier>set</span><span class=special>(</span><span class=number>42</span><span class=special>) </span>#<span class=identifier>Result </span><span class=identifier>disappears
|
||||
</span><span class=special>>>> </span><span class=identifier>y</span><span class=special>.</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>get</span><span class=special>() </span>#<span class=identifier>No </span><span class=identifier>crash</span><span class=special>, </span><span class=identifier>but </span><span class=identifier>still </span><span class=identifier>bad
|
||||
</span><span class=number>3.14
|
||||
</span></pre></code>
|
||||
<p>
|
||||
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>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
Notice that the data member <tt>z</tt> is held by class Y using a raw
|
||||
pointer. Now we have a potential dangling pointer problem inside Y:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>y</span><span class=special>, </span><span class=identifier>z</span><span class=special>) </span>#<span class=identifier>y </span><span class=identifier>refers </span><span class=identifier>to </span><span class=identifier>z
|
||||
</span><span class=special>>>> </span><span class=identifier>del </span><span class=identifier>z </span>#<span class=identifier>Kill </span><span class=identifier>the </span><span class=identifier>z </span><span class=identifier>object
|
||||
</span><span class=special>>>> </span><span class=identifier>y</span><span class=special>.</span><span class=identifier>z_value</span><span class=special>() </span>#<span class=identifier>CRASH</span><span class=special>!
|
||||
</span></pre></code>
|
||||
<p>
|
||||
For reference, here's the implementation of <tt>f</tt> again:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>X</span><span class=special>& </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></code>
|
||||
<p>
|
||||
Here's what's happening:</p>
|
||||
<ol><li><tt>f</tt> is called passing in a reference to <tt>y</tt> and a pointer to <tt>z</tt></li><li>A pointer to <tt>z</tt> is held by <tt>y</tt></li><li>A reference to <tt>y.x</tt> is returned</li><li><tt>z</tt> is deleted. <tt>y.z</tt> is a dangling pointer</li><li><tt>y.z_value()</tt> is called</li><li><tt>z->value()</tt> is called</li><li><b>BOOM!</b></li></ol><a name="call_policies"></a><h2>Call Policies</h2><p>
|
||||
Call Policies may be used in situations such as the example detailed above.
|
||||
In our example, <tt>return_internal_reference</tt> and <tt>with_custodian_and_ward</tt>
|
||||
are our friends:</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
What are the <tt>1</tt> and <tt>2</tt> parameters, you ask?</p>
|
||||
<code><pre>
|
||||
<span class=identifier>return_internal_reference</span><span class=special><</span><span class=number>1
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Informs Boost.Python that the first argument, in our case <tt>Y& y</tt>, is the
|
||||
owner of the returned reference: <tt>X&</tt>. The "<tt>1</tt>" simply specifies the
|
||||
first argument. In short: "return an internal reference <tt>X&</tt> owned by the
|
||||
1st argument <tt>Y& y</tt>".</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
Informs Boost.Python that the lifetime of the argument indicated by ward
|
||||
(i.e. the 2nd argument: <tt>Z* z</tt>) is dependent on the lifetime of the
|
||||
argument indicated by custodian (i.e. the 1st argument: <tt>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>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<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">
|
||||
here</a>.</p>
|
||||
<ul><li><b>with_custodian_and_ward</b><br> Ties lifetimes of the arguments</li><li><b>with_custodian_and_ward_postcall</b><br> Ties lifetimes of the arguments and results</li><li><b>return_internal_reference</b><br> Ties lifetime of one argument to that of result</li><li><b>return_value_policy<T> with T one of:</b><br></li><li><b>reference_existing_object</b><br>naïve (dangerous) approach</li><li><b>copy_const_reference</b><br>Boost.Python v1 approach</li><li><b>copy_non_const_reference</b><br></li><li><b>manage_new_object</b><br> Adopt a pointer and hold the instance</li></ul><table width="80%" border="0" align="center">
|
||||
<tr>
|
||||
<td class="note_box">
|
||||
<img src="theme/smiley.gif"></img> <b>Remember the Zen, Luke:</b><br><br>
|
||||
"Explicit is better than implicit"<br>
|
||||
"In the face of ambiguity, refuse the temptation to guess"<br> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="default_arguments.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,77 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Class Data Members</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="constructors.html">
|
||||
<link rel="next" href="class_properties.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Class Data Members</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="constructors.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="class_properties.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<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 <b>read-only</b> or
|
||||
<b>read-write</b>. Consider this class <tt>Var</tt>:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>struct </span><span class=identifier>Var
|
||||
</span><span class=special>{
|
||||
</span><span class=identifier>Var</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>name</span><span class=special>) </span><span class=special>: </span><span class=identifier>name</span><span class=special>(</span><span class=identifier>name</span><span class=special>), </span><span class=identifier>value</span><span class=special>() </span><span class=special>{}
|
||||
</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=keyword>const </span><span class=identifier>name</span><span class=special>;
|
||||
</span><span class=keyword>float </span><span class=identifier>value</span><span class=special>;
|
||||
</span><span class=special>};
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Our C++ <tt>Var</tt> class and its data members can be exposed to Python:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>class_</span><span class=special><</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></code>
|
||||
<p>
|
||||
Then, in Python:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>Var</span><span class=special>(</span><span class=literal>'pi'</span><span class=special>)
|
||||
</span><span class=special>>>> </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>print </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>name</span><span class=special>, </span><span class=literal>'is around'</span><span class=special>, </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>value
|
||||
</span><span class=identifier>pi </span><span class=identifier>is </span><span class=identifier>around </span><span class=number>3.14
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Note that <tt>name</tt> is exposed as <b>read-only</b> while <tt>value</tt> is exposed
|
||||
as <b>read-write</b>.</p>
|
||||
<code><pre>
|
||||
>>> x.name = 'e' # can't change name
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
AttributeError: can't set attribute
|
||||
</pre></code><table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="constructors.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="class_properties.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,109 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Class Operators/Special Functions</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="class_virtual_functions.html">
|
||||
<link rel="next" href="functions.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Class Operators/Special Functions</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_virtual_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<a name="python_operators"></a><h2>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>FilePos</tt> and a set of operators that take
|
||||
on FilePos instances:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>class </span><span class=identifier>FilePos </span><span class=special>{ </span><span class=comment>/*...*/ </span><span class=special>};
|
||||
|
||||
</span><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></code>
|
||||
<p>
|
||||
The class and the various operators can be mapped to Python rather easily
|
||||
and intuitively:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>class_</span><span class=special><</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>// __rsub__
|
||||
</span><span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>self </span><span class=special>+= </span><span class=keyword>int</span><span class=special>()) </span><span class=comment>// __iadd__
|
||||
</span><span class=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></code>
|
||||
<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>self</tt> refers to FilePos object. Also, not every class <tt>T</tt> that
|
||||
you might need to interact with in an operator expression is (cheaply)
|
||||
default-constructible. You can use <tt>other<T>()</tt> in place of an actual
|
||||
<tt>T</tt> instance when writing "self expressions".</p>
|
||||
<a name="special_methods"></a><h2>Special Methods</h2><p>
|
||||
Python has a few more <i>Special Methods</i>. 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 <i>special functions</i>. Example:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>class </span><span class=identifier>Rational
|
||||
</span><span class=special>{ </span><span class=keyword>operator </span><span class=keyword>double</span><span class=special>() </span><span class=keyword>const</span><span class=special>; </span><span class=special>};
|
||||
|
||||
</span><span class=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=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></code>
|
||||
<p>
|
||||
Need we say more?</p>
|
||||
<table width="80%" border="0" align="center">
|
||||
<tr>
|
||||
<td class="note_box">
|
||||
<img src="theme/lens.gif"></img> What is the business of <tt>operator<<</tt> <tt>.def(str(self))</tt>?
|
||||
Well, the method <tt>str</tt> requires the <tt>operator<<</tt> to do its work (i.e.
|
||||
<tt>operator<<</tt> is used by the method defined by def(str(self)). </td>
|
||||
</tr>
|
||||
</table>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_virtual_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,81 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Class Properties</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="class_data_members.html">
|
||||
<link rel="next" href="inheritance.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Class Properties</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_data_members.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="inheritance.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<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>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<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>Num</tt> class using Boost.Python:</p>
|
||||
<code><pre>
|
||||
<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>Var</span><span class=special>::</span><span class=identifier>get</span><span class=special>)
|
||||
</span><span class=special>.</span><span class=identifier>add_property</span><span class=special>(</span><span class=string>"value"</span><span class=special>, </span><span class=special>&</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>get</span><span class=special>, </span><span class=special>&</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>set</span><span class=special>);
|
||||
</span></pre></code>
|
||||
<p>
|
||||
And at last, in Python:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </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=identifier>error</span><span class=special>!
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Take note that the class property <tt>rovalue</tt> is exposed as <b>read-only</b>
|
||||
since the <tt>rovalue</tt> setter member function is not passed in:</p>
|
||||
<code><pre>
|
||||
<span class=special>.</span><span class=identifier>add_property</span><span class=special>(</span><span class=string>"rovalue"</span><span class=special>, </span><span class=special>&</span><span class=identifier>Var</span><span class=special>::</span><span class=identifier>get</span><span class=special>)
|
||||
</span></pre></code>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_data_members.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="inheritance.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,227 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Class Virtual Functions</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="inheritance.html">
|
||||
<link rel="next" href="class_operators_special_functions.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Class Virtual Functions</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="inheritance.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="class_operators_special_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
In this section, we shall learn how to make functions behave
|
||||
polymorphically through virtual functions. Continuing our example, let us
|
||||
add a virtual function to our <tt>Base</tt> class:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>struct </span><span class=identifier>Base
|
||||
</span><span class=special>{
|
||||
</span><span class=keyword>virtual </span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() </span><span class=special>= </span><span class=number>0</span><span class=special>;
|
||||
</span><span class=special>};
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Since <tt>f</tt> is a pure virtual function, <tt>Base</tt> is now an abstract
|
||||
class. Given an instance of our class, the free function <tt>call_f</tt>
|
||||
calls some implementation of this virtual function in a concrete
|
||||
derived class:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>int </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>Base</span><span class=special>& </span><span class=identifier>b</span><span class=special>) </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>b</span><span class=special>.</span><span class=identifier>f</span><span class=special>(); </span><span class=special>}
|
||||
</span></pre></code>
|
||||
<p>
|
||||
To allow this function to be implemented in a Python derived class, we
|
||||
need to create a class wrapper:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>struct </span><span class=identifier>BaseWrap </span><span class=special>: </span><span class=identifier>Base
|
||||
</span><span class=special>{
|
||||
</span><span class=identifier>BaseWrap</span><span class=special>(</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self_</span><span class=special>)
|
||||
</span><span class=special>: </span><span class=identifier>self</span><span class=special>(</span><span class=identifier>self_</span><span class=special>) </span><span class=special>{}
|
||||
</span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>call_method</span><span class=special><</span><span class=keyword>int</span><span class=special>>(</span><span class=identifier>self</span><span class=special>, </span><span class=string>"f"</span><span class=special>); </span><span class=special>}
|
||||
</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self</span><span class=special>;
|
||||
</span><span class=special>};
|
||||
</span></pre></code>
|
||||
<table width="80%" border="0" align="center">
|
||||
<tr>
|
||||
<td class="note_box">
|
||||
<img src="theme/lens.gif"></img> <b>member function and methods</b><br><br> Python, like
|
||||
many object oriented languages uses the term <b>methods</b>. Methods
|
||||
correspond roughly to C++'s <b>member functions</b> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
Our class wrapper <tt>BaseWrap</tt> is derived from <tt>Base</tt>. Its overridden
|
||||
virtual member function <tt>f</tt> in effect calls the corresponding method
|
||||
of the Python object <tt>self</tt>, which is a pointer back to the Python
|
||||
<tt>Base</tt> object holding our <tt>BaseWrap</tt> instance.</p>
|
||||
<table width="80%" border="0" align="center">
|
||||
<tr>
|
||||
<td class="note_box">
|
||||
<img src="theme/note.gif"></img> <b>Why do we need BaseWrap?</b><br><br>
|
||||
|
||||
<i>You may ask</i>, "Why do we need the <tt>BaseWrap</tt> derived class? This could
|
||||
have been designed so that everything gets done right inside of
|
||||
Base."<br><br>
|
||||
|
||||
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.<br><br>
|
||||
|
||||
Note however that you don't need to do this to get methods overridden
|
||||
in Python to behave virtually when called <i>from</i> <b>Python</b>. The only
|
||||
time you need to do the <tt>BaseWrap</tt> dance is when you have a virtual
|
||||
function that's going to be overridden in Python and called
|
||||
polymorphically <i>from</i> <b>C++</b>. </td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
Wrapping <tt>Base</tt> and the free function <tt>call_f</tt>:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>class_</span><span class=special><</span><span class=identifier>Base</span><span class=special>, </span><span class=identifier>BaseWrap</span><span class=special>, </span><span class=identifier>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=identifier>no_init</span><span class=special>)
|
||||
</span><span class=special>;
|
||||
</span><span class=identifier>def</span><span class=special>(</span><span class=string>"call_f"</span><span class=special>, </span><span class=identifier>call_f</span><span class=special>);
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Notice that we parameterized the <tt>class_</tt> template with <tt>BaseWrap</tt> as the
|
||||
second parameter. What is <tt>noncopyable</tt>? Without it, the library will try
|
||||
to create code for converting Base return values of wrapped functions to
|
||||
Python. To do that, it needs Base's copy constructor... which isn't
|
||||
available, since Base is an abstract class.</p>
|
||||
<p>
|
||||
In Python, let us try to instantiate our <tt>Base</tt> class:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=identifier>base </span><span class=special>= </span><span class=identifier>Base</span><span class=special>()
|
||||
</span><span class=identifier>AttributeError</span><span class=special>: </span><span class=special>...
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Why is it an error? <tt>Base</tt> is an abstract class. As such it is advisable
|
||||
to define the Python wrapper with <tt>no_init</tt> as we have done above. Doing
|
||||
so will disallow abstract base classes such as <tt>Base</tt> to be instantiated.</p>
|
||||
<a name="deriving_a_python_class"></a><h2>Deriving a Python class</h2><p>
|
||||
Now, at last, we can even derive from our base class <tt>Base</tt> in Python:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=keyword>class </span><span class=identifier>Derived</span><span class=special>(</span><span class=identifier>Base</span><span class=special>):
|
||||
</span><span class=special>... </span><span class=identifier>def </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
|
||||
</span><span class=special>... </span><span class=keyword>return </span><span class=number>42
|
||||
</span><span class=special>...
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Cool eh? A Python class deriving from a C++ class!</p>
|
||||
<p>
|
||||
Let's now make an instance of our Python class <tt>Derived</tt>:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=identifier>derived </span><span class=special>= </span><span class=identifier>Derived</span><span class=special>()
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Calling <tt>derived.f()</tt>:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=identifier>derived</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
|
||||
</span><span class=number>42
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Will yield the expected result. Finally, calling calling the free function
|
||||
<tt>call_f</tt> with <tt>derived</tt> as argument:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>derived</span><span class=special>)
|
||||
</span><span class=number>42
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Will also yield the expected result.</p>
|
||||
<p>
|
||||
Here's what's happening:</p>
|
||||
<ol><li><tt>call_f(derived)</tt> is called in Python</li><li>This corresponds to <tt>def("call_f", call_f);</tt>. Boost.Python dispatches this call.</li><li><tt>int call_f(Base& b) { return b.f(); }</tt> accepts the call.</li><li>The overridden virtual function <tt>f</tt> of <tt>BaseWrap</tt> is called.</li><li><tt>call_method<int>(self, "f");</tt> dispatches the call back to Python.</li><li><tt>def f(self): return 42</tt> is finally called.</li></ol><p>
|
||||
Rewind back to our <tt>Base</tt> class, if its member function <tt>f</tt> was not
|
||||
declared as pure virtual:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>struct </span><span class=identifier>Base
|
||||
</span><span class=special>{
|
||||
</span><span class=keyword>virtual </span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=number>0</span><span class=special>; </span><span class=special>}
|
||||
</span><span class=special>};
|
||||
</span></pre></code>
|
||||
<p>
|
||||
And instead is implemented to return <tt>0</tt>, as shown above.</p>
|
||||
<code><pre>
|
||||
<span class=keyword>struct </span><span class=identifier>BaseWrap </span><span class=special>: </span><span class=identifier>Base
|
||||
</span><span class=special>{
|
||||
</span><span class=identifier>BaseWrap</span><span class=special>(</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self_</span><span class=special>)
|
||||
</span><span class=special>: </span><span class=identifier>self</span><span class=special>(</span><span class=identifier>self_</span><span class=special>) </span><span class=special>{}
|
||||
</span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>call_method</span><span class=special><</span><span class=keyword>int</span><span class=special>>(</span><span class=identifier>self</span><span class=special>, </span><span class=string>"f"</span><span class=special>); </span><span class=special>}
|
||||
</span><span class=keyword>static </span><span class=keyword>int </span><span class=identifier>default_f</span><span class=special>(</span><span class=identifier>Base</span><span class=special>* </span><span class=identifier>b</span><span class=special>) </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>b</span><span class=special>-></span><span class=identifier>Base</span><span class=special>::</span><span class=identifier>f</span><span class=special>(); </span><span class=special>} </span><span class=comment>// <<=== added
|
||||
</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self</span><span class=special>;
|
||||
</span><span class=special>};
|
||||
</span></pre></code>
|
||||
<p>
|
||||
then, our Boost.Python wrapper:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>class_</span><span class=special><</span><span class=identifier>Base</span><span class=special>, </span><span class=identifier>BaseWrap</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>BaseWrap</span><span class=special>::</span><span class=identifier>default_f</span><span class=special>)
|
||||
</span><span class=special>;
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Note that we are allowing <tt>Base</tt> objects to be instantiated this time,
|
||||
unlike before where we specifically defined the <tt>class_<Base></tt> with
|
||||
<tt>no_init</tt>.</p>
|
||||
<p>
|
||||
In Python, the results would be as expected:</p>
|
||||
<code><pre>
|
||||
<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=identifier>def </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
|
||||
</span><span class=special>... </span><span class=keyword>return </span><span class=number>42
|
||||
</span><span class=special>...
|
||||
</span><span class=special>>>> </span><span class=identifier>derived </span><span class=special>= </span><span class=identifier>Derived</span><span class=special>()
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Calling <tt>base.f()</tt>:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=identifier>base</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
|
||||
</span><span class=number>0
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Calling <tt>derived.f()</tt>:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=identifier>derived</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
|
||||
</span><span class=number>42
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Calling <tt>call_f</tt>, passing in a <tt>base</tt> object:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>base</span><span class=special>)
|
||||
</span><span class=number>0
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Calling <tt>call_f</tt>, passing in a <tt>derived</tt> object:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>derived</span><span class=special>)
|
||||
</span><span class=number>42
|
||||
</span></pre></code>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="inheritance.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="class_operators_special_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,102 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Constructors</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="exposing_classes.html">
|
||||
<link rel="next" href="class_data_members.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Constructors</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="exposing_classes.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="class_data_members.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
Our previous example didn't have any explicit constructors.
|
||||
Since <tt>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>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
We may wish to wrap a class with a non-default constructor. Let us
|
||||
build on our previous example:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>struct </span><span class=identifier>World
|
||||
</span><span class=special>{
|
||||
</span><span class=identifier>World</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>): </span><span class=identifier>msg</span><span class=special>(</span><span class=identifier>msg</span><span class=special>) </span><span class=special>{} </span><span class=comment>// added constructor
|
||||
</span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>) </span><span class=special>{ </span><span class=keyword>this</span><span class=special>-></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></code>
|
||||
<p>
|
||||
This time <tt>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_<World></tt> about the constructor we want to
|
||||
expose instead.</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
<tt>init<std::string>()</tt> exposes the constructor taking in a
|
||||
<tt>std::string</tt> (in Python, constructors are spelled
|
||||
"<tt>"__init__"</tt>").</p>
|
||||
<p>
|
||||
We can expose additional constructors by passing more <tt>init<...></tt>s to
|
||||
the <tt>def()</tt> member function. Say for example we have another World
|
||||
constructor taking in two doubles:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>class_</span><span class=special><</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></code>
|
||||
<p>
|
||||
On the other hand, if we do not wish to expose any constructors at
|
||||
all, we may use <tt>no_init</tt> instead:</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
This actually adds an <tt>__init__</tt> method which always raises a
|
||||
Python RuntimeError exception.</p>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="exposing_classes.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="class_data_members.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,118 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Default Arguments</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="call_policies.html">
|
||||
<link rel="next" href="object_interface.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Default Arguments</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="call_policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="object_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
Boost.Python wraps (member) function pointers. Unfortunately, C++ function
|
||||
pointers carry no default argument info. Take a function <tt>f</tt> with default
|
||||
arguments:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>int </span><span class=identifier>f</span><span class=special>(</span><span class=keyword>int</span><span class=special>, </span><span class=keyword>double </span><span class=special>= </span><span class=number>3.14</span><span class=special>, </span><span class=keyword>char </span><span class=keyword>const</span><span class=special>* </span><span class=special>= </span><span class=string>"hello"</span><span class=special>);
|
||||
</span></pre></code>
|
||||
<p>
|
||||
But the type of a pointer to the function <tt>f</tt> has no information
|
||||
about its default arguments:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>int</span><span class=special>(*</span><span class=identifier>g</span><span class=special>)(</span><span class=keyword>int</span><span class=special>,</span><span class=keyword>double</span><span class=special>,</span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*) </span><span class=special>= </span><span class=identifier>f</span><span class=special>; </span><span class=comment>// defaults lost!
|
||||
</span></pre></code>
|
||||
<p>
|
||||
When we pass this function pointer to the <tt>def</tt> function, there is no way
|
||||
to retrieve the default arguments:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>def</span><span class=special>(</span><span class=string>"f"</span><span class=special>, </span><span class=identifier>f</span><span class=special>); </span><span class=comment>// defaults lost!
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Because of this, when wrapping C++ code in earlier versions of
|
||||
Boost.Python, we had to resort to writing thin wrappers:</p>
|
||||
<code><pre>
|
||||
<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>/*...*/
|
||||
|
||||
// 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></code>
|
||||
<p>
|
||||
When you want to wrap functions (or member functions) that either:</p>
|
||||
<ul><li>have default arguments, or</li><li>are overloaded with a common sequence of initial arguments</li></ul><p>
|
||||
Boost.Python now has a way to make it easier.</p>
|
||||
<p>
|
||||
For instance, given a function:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>int </span><span class=identifier>foo</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>char </span><span class=identifier>b </span><span class=special>= </span><span class=number>1</span><span class=special>, </span><span class=keyword>unsigned </span><span class=identifier>c </span><span class=special>= </span><span class=number>2</span><span class=special>, </span><span class=keyword>double </span><span class=identifier>d </span><span class=special>= </span><span class=number>3</span><span class=special>);
|
||||
</span></pre></code>
|
||||
<p>
|
||||
The macro invocation:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class=special>(</span><span class=identifier>foo_overloads</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=number>1</span><span class=special>, </span><span class=number>4</span><span class=special>)
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Will automatically create the thin wrappers for us. This macro will create
|
||||
a class <tt>foo_overloads</tt> that can be passed on to <tt>def(...)</tt>. The third
|
||||
and fourth macro argument are the minimum arguments and maximum arguments,
|
||||
respectively. In our <tt>foo</tt> function the minimum number of arguments is 1
|
||||
and the maximum number of arguments is 4. The <tt>def(...)</tt> function will
|
||||
automatically add all the foo variants for us:</p>
|
||||
<code><pre>
|
||||
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>"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></code>
|
||||
<p>
|
||||
A similar facility is provided for class constructors, again, with
|
||||
default arguments or a sequence of overloads. Remember init<...>? For example,
|
||||
given a class X with a constructor:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>struct </span><span class=identifier>X
|
||||
</span><span class=special>{
|
||||
</span><span class=identifier>X</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>char </span><span class=identifier>b </span><span class=special>= </span><span class=literal>'D'</span><span class=special>, </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>c </span><span class=special>= </span><span class=string>"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></code>
|
||||
<p>
|
||||
You can easily add this constructor to Boost.Python in one shot:</p>
|
||||
<code><pre>
|
||||
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=identifier>init</span><span class=special><</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></code>
|
||||
<p>
|
||||
Notice the use of <tt>init<...></tt> and <tt>optional<...></tt> to signify the default
|
||||
(optional arguments).</p>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="call_policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="object_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,117 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Derived Object types</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="basic_interface.html">
|
||||
<link rel="next" href="extracting_c___objects.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Derived Object types</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="basic_interface.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="extracting_c___objects.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
Boost.Python comes with a set of derived <tt>object</tt> types corresponding to
|
||||
that of Python's:</p>
|
||||
<ul><li>list</li><li>dict</li><li>tuple</li><li>str</li><li>long_</li><li>enum</li></ul><p>
|
||||
These derived <tt>object</tt> types act like real Python types. For instance:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>str</span><span class=special>(</span><span class=number>1</span><span class=special>) </span><span class=special>==> </span><span class=string>"1"
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Wherever appropriate, a particular derived <tt>object</tt> has corresponding
|
||||
Python type's methods. For instance, <tt>dict</tt> has a <tt>keys()</tt> method:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>d</span><span class=special>.</span><span class=identifier>keys</span><span class=special>()
|
||||
</span></pre></code>
|
||||
<p>
|
||||
<tt>make_tuple</tt> is provided for declaring <i>tuple literals</i>. Example:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>make_tuple</span><span class=special>(</span><span class=number>123</span><span class=special>, </span><span class=literal>'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></code>
|
||||
<p>
|
||||
In C++, when Boost.Python <tt>object</tt>s are used as arguments to functions,
|
||||
subtype matching is required. For example, when a function <tt>f</tt>, as
|
||||
declared below, is wrapped, it will only accept instances of Python's
|
||||
<tt>str</tt> type and subtypes.</p>
|
||||
<code><pre>
|
||||
<span class=keyword>void </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>str </span><span class=identifier>name</span><span class=special>)
|
||||
</span><span class=special>{
|
||||
</span><span class=identifier>object </span><span class=identifier>n2 </span><span class=special>= </span><span class=identifier>name</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>"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></code>
|
||||
<p>
|
||||
In finer detail:</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
Illustrates that we provide versions of the str type's methods as C++
|
||||
member functions.</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
Demonstrates that you can write the C++ equivalent of <tt>"format" % x,y,z</tt>
|
||||
in Python, which is useful since there's no easy way to do that in std C++.</p>
|
||||
<p>
|
||||
<img src="theme/alert.gif"></img> <b>Beware</b> the common pitfall of forgetting that the constructors
|
||||
of most of Python's mutable types make copies, just as in Python.</p>
|
||||
<p>
|
||||
Python:</p>
|
||||
<code><pre>
|
||||
<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=identifier>copies </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__
|
||||
</span><span class=special>>>> </span><span class=identifier>d</span><span class=special>[</span><span class=literal>'whatever'</span><span class=special>] </span>#<span class=identifier>modifies </span><span class=identifier>the </span><span class=identifier>copy
|
||||
</span></pre></code>
|
||||
<p>
|
||||
C++:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>dict </span><span class=identifier>d</span><span class=special>(</span><span class=identifier>x</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>"__dict__"</span><span class=special>)); </span>#<span class=identifier>copies </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__
|
||||
</span><span class=identifier>d</span><span class=special>[</span><span class=literal>'whatever'</span><span class=special>] </span><span class=special>= </span><span class=number>3</span><span class=special>; </span>#<span class=identifier>modifies </span><span class=identifier>the </span><span class=identifier>copy
|
||||
</span></pre></code>
|
||||
<a name="class__lt_t_gt__as_objects"></a><h2>class_<T> as objects</h2><p>
|
||||
Due to the dynamic nature of Boost.Python objects, any <tt>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>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="basic_interface.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="extracting_c___objects.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,95 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Enums</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="extracting_c___objects.html">
|
||||
<link rel="next" href="iterators.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Enums</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="extracting_c___objects.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="iterators.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
Boost.Python has a nifty facility to capture and wrap C++ enums. While
|
||||
Python has no <tt>enum</tt> type, we'll often want to expose our C++ enums to
|
||||
Python as an <tt>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>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
the construct:</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
can be used to expose to Python. The new enum type is created in the
|
||||
current <tt>scope()</tt>, which is usually the current module. The snippet above
|
||||
creates a Python class derived from Python's <tt>int</tt> type which is
|
||||
associated with the C++ type passed as its first parameter.</p>
|
||||
<table width="80%" border="0" align="center">
|
||||
<tr>
|
||||
<td class="note_box">
|
||||
<img src="theme/lens.gif"></img> <b>what is a scope?</b><br><br> 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">
|
||||
here</a>. </td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
You can access those values in Python as</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
where my_module is the module where the enum is declared. You can also
|
||||
create a new scope around a class:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>scope </span><span class=identifier>in_X</span><span class=special>(</span><span class=identifier>class_</span><span class=special><</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></code>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="extracting_c___objects.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="iterators.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,60 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Exception Translation</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="iterators.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Exception Translation</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="iterators.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<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>
|
||||
<code><pre>
|
||||
<span class=identifier>raise </span><span class=identifier>RuntimeError</span><span class=special>, </span><span class=literal>'unidentifiable C++ Exception'
|
||||
</span></pre></code>
|
||||
<p>
|
||||
Users may provide custom translation. Here's an example:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>struct </span><span class=identifier>PodBayDoorException</span><span class=special>;
|
||||
</span><span class=keyword>void </span><span class=identifier>translator</span><span class=special>(</span><span class=identifier>PodBayDoorException</span><span class=special>& </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></code>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="iterators.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><img src="theme/r_arr_disabled.gif" border="0"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,79 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Exposing Classes</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="building_hello_world.html">
|
||||
<link rel="next" href="constructors.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Exposing Classes</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="building_hello_world.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="constructors.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<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>
|
||||
<code><pre>
|
||||
<span class=keyword>struct </span><span class=identifier>World
|
||||
</span><span class=special>{
|
||||
</span><span class=keyword>void </span><span class=identifier>set</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string </span><span class=identifier>msg</span><span class=special>) </span><span class=special>{ </span><span class=keyword>this</span><span class=special>-></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></code>
|
||||
<p>
|
||||
We can expose this to Python by writing a corresponding Boost.Python
|
||||
C++ Wrapper:</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
Here, we wrote a C++ class wrapper that exposes the member functions
|
||||
<tt>greet</tt> and <tt>set</tt>. Now, after building our module as a shared library, we
|
||||
may use our class <tt>World</tt> in Python. Here's a sample Python session:</p>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=identifier>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=literal>'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=literal>'howdy'
|
||||
</span></pre></code>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="building_hello_world.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="constructors.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,79 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Extracting C++ objects</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="derived_object_types.html">
|
||||
<link rel="next" href="enums.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Extracting C++ objects</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="derived_object_types.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="enums.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
At some point, we will need to get C++ values out of object instances. This
|
||||
can be achieved with the <tt>extract<T></tt> function. Consider the following:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>double </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>o</span><span class=special>.</span><span class=identifier>attr</span><span class=special>(</span><span class=string>"length"</span><span class=special>); </span><span class=comment>// compile error
|
||||
</span></pre></code>
|
||||
<p>
|
||||
In the code above, we got a compiler error because Boost.Python
|
||||
<tt>object</tt> can't be implicitly converted to <tt>double</tt>s. Instead, what
|
||||
we wanted to do above can be achieved by writing:</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
The first line attempts to extract the "length" attribute of the
|
||||
Boost.Python <tt>object</tt> <tt>o</tt>. The second line attempts to <i>extract</i> the
|
||||
<tt>Vec2</tt> object from held by the Boost.Python <tt>object</tt> <tt>o</tt>.</p>
|
||||
<p>
|
||||
Take note that we said "attempt to" above. What if the Boost.Python
|
||||
<tt>object</tt> <tt>o</tt> does not really hold a <tt>Vec2</tt> type? This is certainly
|
||||
a possibility considering the dynamic nature of Python <tt>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>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
<img src="theme/bulb.gif"></img> The astute reader might have noticed that the <tt>extract<T></tt>
|
||||
facility in fact solves the mutable copying problem:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>dict </span><span class=identifier>d </span><span class=special>= </span><span class=identifier>extract</span><span class=special><</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=literal>'whatever'</span><span class=special>] </span><span class=special>= </span><span class=number>3</span><span class=special>; </span>#<span class=identifier>modifies </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__dict__ </span><span class=special>!
|
||||
</span></pre></code>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="derived_object_types.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="enums.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,73 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Functions</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="class_operators_special_functions.html">
|
||||
<link rel="next" href="call_policies.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Functions</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_operators_special_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="call_policies.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
In this chapter, we'll look at Boost.Python powered functions in closer
|
||||
detail. We shall see some facilities to make exposing C++ functions to
|
||||
Python safe from potential pifalls such as dangling pointers and
|
||||
references. We shall 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>
|
||||
<blockquote><p><i>Read on...</i></p></blockquote><p>
|
||||
But before you do, you might want to fire up Python 2.2 or later and type
|
||||
<tt>>>> import this</tt>.</p>
|
||||
<code><pre>
|
||||
>>> 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 *right* 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></code><table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_operators_special_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="call_policies.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
511
doc/tutorial/doc/html/boostbook.css
Normal file
@@ -0,0 +1,511 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2004 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to 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)
|
||||
=============================================================================*/
|
||||
|
||||
/*=============================================================================
|
||||
Body defaults
|
||||
=============================================================================*/
|
||||
|
||||
body
|
||||
{
|
||||
margin: 1em;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Paragraphs
|
||||
=============================================================================*/
|
||||
|
||||
p
|
||||
{
|
||||
text-align: left;
|
||||
font-size: 10pt;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Program listings
|
||||
=============================================================================*/
|
||||
|
||||
/* Code on paragraphs */
|
||||
p tt.computeroutput
|
||||
{
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
pre.synopsis
|
||||
{
|
||||
font-size: 90%;
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
|
||||
}
|
||||
|
||||
.programlisting,
|
||||
.screen
|
||||
{
|
||||
font-size: 9pt;
|
||||
display: block;
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
|
||||
}
|
||||
|
||||
/* Program listings in tables don't get borders */
|
||||
td .programlisting,
|
||||
td .screen
|
||||
{
|
||||
margin: 0pc 0pc 0pc 0pc;
|
||||
padding: 0pc 0pc 0pc 0pc;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Headings
|
||||
=============================================================================*/
|
||||
|
||||
h1, h2, h3, h4, h5, h6
|
||||
{
|
||||
text-align: left;
|
||||
margin: 1em 0em 0.5em 0em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 { font: 140% }
|
||||
h2 { font: bold 140% }
|
||||
h3 { font: bold 130% }
|
||||
h4 { font: bold 120% }
|
||||
h5 { font: italic 110% }
|
||||
h6 { font: italic 100% }
|
||||
|
||||
/* Top page titles */
|
||||
title,
|
||||
h1.title,
|
||||
h2.title
|
||||
h3.title,
|
||||
h4.title,
|
||||
h5.title,
|
||||
h6.title,
|
||||
.refentrytitle
|
||||
{
|
||||
font-weight: bold;
|
||||
margin-bottom: 1pc;
|
||||
}
|
||||
|
||||
h1.title { font-size: 140% }
|
||||
h2.title { font-size: 140% }
|
||||
h3.title { font-size: 130% }
|
||||
h4.title { font-size: 120% }
|
||||
h5.title { font-size: 110% }
|
||||
h6.title { font-size: 100% }
|
||||
|
||||
.section h1
|
||||
{
|
||||
margin: 0em 0em 0.5em 0em;
|
||||
font-size: 140%;
|
||||
}
|
||||
|
||||
.section h2 { font-size: 140% }
|
||||
.section h3 { font-size: 130% }
|
||||
.section h4 { font-size: 120% }
|
||||
.section h5 { font-size: 110% }
|
||||
.section h6 { font-size: 100% }
|
||||
|
||||
/* Code on titles */
|
||||
h1 tt.computeroutput { font-size: 140% }
|
||||
h2 tt.computeroutput { font-size: 140% }
|
||||
h3 tt.computeroutput { font-size: 130% }
|
||||
h4 tt.computeroutput { font-size: 120% }
|
||||
h5 tt.computeroutput { font-size: 110% }
|
||||
h6 tt.computeroutput { font-size: 100% }
|
||||
|
||||
/*=============================================================================
|
||||
Author
|
||||
=============================================================================*/
|
||||
|
||||
h3.author
|
||||
{
|
||||
font-size: 100%
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Lists
|
||||
=============================================================================*/
|
||||
|
||||
li
|
||||
{
|
||||
font-size: 10pt;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
/* Unordered lists */
|
||||
ul
|
||||
{
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Ordered lists */
|
||||
ol
|
||||
{
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Links
|
||||
=============================================================================*/
|
||||
|
||||
a
|
||||
{
|
||||
text-decoration: none; /* no underline */
|
||||
}
|
||||
|
||||
a:hover
|
||||
{
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Spirit style navigation
|
||||
=============================================================================*/
|
||||
|
||||
.spirit-nav
|
||||
{
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.spirit-nav a
|
||||
{
|
||||
color: white;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
.spirit-nav img
|
||||
{
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Table of contents
|
||||
=============================================================================*/
|
||||
|
||||
.toc
|
||||
{
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.1pc 1pc 0.1pc 1pc;
|
||||
font-size: 80%;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.boost-toc
|
||||
{
|
||||
float: right;
|
||||
padding: 0.5pc;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Tables
|
||||
=============================================================================*/
|
||||
|
||||
.table-title,
|
||||
div.table p.title
|
||||
{
|
||||
margin-left: 4%;
|
||||
padding-right: 0.5em;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
.informaltable table,
|
||||
.table table
|
||||
{
|
||||
width: 92%;
|
||||
margin-left: 4%;
|
||||
margin-right: 4%;
|
||||
}
|
||||
|
||||
div.informaltable table,
|
||||
div.table table
|
||||
{
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
/* Table Cells */
|
||||
div.informaltable table tr td,
|
||||
div.table table tr td
|
||||
{
|
||||
padding: 0.5em;
|
||||
text-align: left;
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
div.informaltable table tr th,
|
||||
div.table table tr th
|
||||
{
|
||||
padding: 0.5em 0.5em 0.5em 0.5em;
|
||||
border: 1pt solid white;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Blurbs
|
||||
=============================================================================*/
|
||||
|
||||
div.note,
|
||||
div.tip,
|
||||
div.important,
|
||||
div.caution,
|
||||
div.warning,
|
||||
p.blurb
|
||||
{
|
||||
font-size: 9pt; /* A little bit smaller than the main text */
|
||||
line-height: 1.2;
|
||||
display: block;
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
|
||||
}
|
||||
|
||||
p.blurb img
|
||||
{
|
||||
padding: 1pt;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Variable Lists
|
||||
=============================================================================*/
|
||||
|
||||
/* Make the terms in definition lists bold */
|
||||
div.variablelist dl dt,
|
||||
span.term
|
||||
{
|
||||
font-weight: bold;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
div.variablelist table tbody tr td
|
||||
{
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
padding: 0em 2em 0em 0em;
|
||||
font-size: 10pt;
|
||||
margin: 0em 0em 0.5em 0em;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
div.variablelist dl dt
|
||||
{
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
|
||||
div.variablelist dl dd
|
||||
{
|
||||
margin: 0em 0em 0.5em 2em;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
div.variablelist table tbody tr td p,
|
||||
div.variablelist dl dd p
|
||||
{
|
||||
margin: 0em 0em 0.5em 0em;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Misc
|
||||
=============================================================================*/
|
||||
|
||||
/* Title of books and articles in bibliographies */
|
||||
span.title
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
span.underline
|
||||
{
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
span.strikethrough
|
||||
{
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
/* Copyright, Legal Notice */
|
||||
div div.legalnotice p
|
||||
{
|
||||
text-align: left
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Colors
|
||||
=============================================================================*/
|
||||
|
||||
@media screen
|
||||
{
|
||||
/* Links */
|
||||
a
|
||||
{
|
||||
color: #005a9c;
|
||||
}
|
||||
|
||||
a:visited
|
||||
{
|
||||
color: #9c5a9c;
|
||||
}
|
||||
|
||||
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
|
||||
h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
|
||||
h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
|
||||
{
|
||||
text-decoration: none; /* no underline */
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/* Syntax Highlighting */
|
||||
.keyword { color: #0000AA; }
|
||||
.identifier { color: #000000; }
|
||||
.special { color: #707070; }
|
||||
.preprocessor { color: #402080; }
|
||||
.char { color: teal; }
|
||||
.comment { color: #800000; }
|
||||
.string { color: teal; }
|
||||
.number { color: teal; }
|
||||
.white_bkd { background-color: #FFFFFF; }
|
||||
.dk_grey_bkd { background-color: #999999; }
|
||||
|
||||
/* Copyright, Legal Notice */
|
||||
.copyright
|
||||
{
|
||||
color: #666666;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
div div.legalnotice p
|
||||
{
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
/* Program listing */
|
||||
pre.synopsis
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
.programlisting,
|
||||
.screen
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
td .programlisting,
|
||||
td .screen
|
||||
{
|
||||
border: 0px solid #DCDCDC;
|
||||
}
|
||||
|
||||
/* Blurbs */
|
||||
div.note,
|
||||
div.tip,
|
||||
div.important,
|
||||
div.caution,
|
||||
div.warning,
|
||||
p.blurb
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
/* Table of contents */
|
||||
.toc
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
div.informaltable table tr td,
|
||||
div.table table tr td
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
div.informaltable table tr th,
|
||||
div.table table tr th
|
||||
{
|
||||
background-color: #F0F0F0;
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
/* Misc */
|
||||
span.highlight
|
||||
{
|
||||
color: #00A000;
|
||||
}
|
||||
}
|
||||
|
||||
@media print
|
||||
{
|
||||
/* Links */
|
||||
a
|
||||
{
|
||||
color: black;
|
||||
}
|
||||
|
||||
a:visited
|
||||
{
|
||||
color: black;
|
||||
}
|
||||
|
||||
.spirit-nav
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Program listing */
|
||||
pre.synopsis
|
||||
{
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
.programlisting,
|
||||
.screen
|
||||
{
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
td .programlisting,
|
||||
td .screen
|
||||
{
|
||||
border: 0px solid #DCDCDC;
|
||||
}
|
||||
|
||||
/* Table of contents */
|
||||
.toc
|
||||
{
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
.informaltable table,
|
||||
.table table
|
||||
{
|
||||
border: 1px solid gray;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
div.informaltable table tr td,
|
||||
div.table table tr td
|
||||
{
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
div.informaltable table tr th,
|
||||
div.table table tr th
|
||||
{
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
/* Misc */
|
||||
span.highlight
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
BIN
doc/tutorial/doc/html/images/alert.png
Executable file
|
After Width: | Height: | Size: 603 B |
BIN
doc/tutorial/doc/html/images/home.png
Executable file
|
After Width: | Height: | Size: 358 B |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
BIN
doc/tutorial/doc/html/images/next.png
Executable file
|
After Width: | Height: | Size: 336 B |
BIN
doc/tutorial/doc/html/images/note.png
Executable file
|
After Width: | Height: | Size: 658 B |
BIN
doc/tutorial/doc/html/images/prev.png
Executable file
|
After Width: | Height: | Size: 334 B |
|
Before Width: | Height: | Size: 14 KiB 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
Executable file
|
After Width: | Height: | Size: 640 B |
BIN
doc/tutorial/doc/html/images/up.png
Executable file
|
After Width: | Height: | Size: 370 B |
151
doc/tutorial/doc/html/index.html
Normal file
@@ -0,0 +1,151 @@
|
||||
<!-- 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">
|
||||
<title>Chapter 1. python 1.0</title>
|
||||
<link rel="stylesheet" href="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%">
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</table>
|
||||
<hr>
|
||||
<div class="spirit-nav"><a accesskey="n" href="python/hello.html"><img src="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="id376848"></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="id447173"></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="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">;</span>
|
||||
|
||||
<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">hello</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">def</span><span class="special">(</span><span class="string">"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</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>
|
||||
<span class="emphasis"><em><span class="bold"><b>Next stop... Building your Hello World module
|
||||
from start to finish...</b></span></em></span>
|
||||
</p></blockquote></div>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><small><p>Last revised: August 31, 2006 at 05:59:58 GMT</p></small></td>
|
||||
<td align="right"><small></small></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav"><a accesskey="n" href="python/hello.html"><img src="images/next.png" alt="Next"></a></div>
|
||||
</body>
|
||||
</html>
|
||||
423
doc/tutorial/doc/html/python/embedding.html
Normal file
@@ -0,0 +1,423 @@
|
||||
<!-- 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">
|
||||
<title>Embedding</title>
|
||||
<link rel="stylesheet" href="../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%">
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="object.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../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="id462650"></a>
|
||||
Building embedded programs
|
||||
</h2>
|
||||
<p>
|
||||
To be able to use embedding in your programs, they have to be linked to both
|
||||
Boost.Python's and Python's static link library.
|
||||
</p>
|
||||
<p>
|
||||
Boost.Python's static link library comes in two variants. Both are located
|
||||
in Boost's <tt 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 static link 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="id462747"></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><br><br>
|
||||
</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.<br><br>
|
||||
</li>
|
||||
<li>
|
||||
Call other Python C API routines to use the interpreter.<br><br>
|
||||
</li>
|
||||
<li>
|
||||
Call <a href="http://www.python.org/doc/current/api/initialization.html#l2h-656" target="_top">Py_Finalize</a>()
|
||||
to stop the interpreter and release its resources.
|
||||
</li>
|
||||
</ol></div>
|
||||
<p>
|
||||
(Of course, there can be other C++ code between all of these steps.)
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><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></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/api/refcounts.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.reference_counting_handles_and_objects"></a><h2>
|
||||
<a name="id462914"></a>
|
||||
Reference-counting handles and objects
|
||||
</h2>
|
||||
<p>
|
||||
There are two ways in which a function in the Python/C API can return a
|
||||
<tt class="literal">PyObject*</tt>: as a <span class="emphasis"><em>borrowed reference</em></span>
|
||||
or as a <span class="emphasis"><em>new reference</em></span>. Which of these a function uses,
|
||||
is listed in that function's documentation. The two require slightely different
|
||||
approaches to reference-counting but both can be 'handled' by Boost.Python.
|
||||
</p>
|
||||
<p>
|
||||
For a function returning a <span class="emphasis"><em>borrowed reference</em></span> we'll
|
||||
have to tell the <tt class="literal">handle</tt> that the <tt class="literal">PyObject*</tt>
|
||||
is borrowed with the aptly named <a href="../../../../v2/handle.html#borrowed-spec" target="_top">borrowed</a>
|
||||
function. Two functions returning borrowed references are <a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a>
|
||||
and <a href="http://www.python.org/doc/current/api/moduleObjects.html#l2h-594" target="_top">PyModule_GetDict</a>.
|
||||
The former returns a reference to an already imported module, the latter
|
||||
retrieves a module's namespace dictionary. Let's use them to retrieve the
|
||||
namespace of the <tt class="literal"><span class="underline">_main</span>_</tt>
|
||||
module:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">main_module</span><span class="special">((</span>
|
||||
<span class="identifier">handle</span><span class="special"><>(</span><span class="identifier">borrowed</span><span class="special">(</span><a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a><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>
|
||||
</pre>
|
||||
<p>
|
||||
For a function returning a <span class="emphasis"><em>new reference</em></span> we can just
|
||||
create a <tt class="literal">handle</tt> out of the raw <tt class="literal">PyObject*</tt>
|
||||
without wrapping it in a call to borrowed. One such function that returns
|
||||
a new reference is <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
|
||||
which we'll discuss in the next section.
|
||||
</p>
|
||||
<p class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Handle is a class <span class="emphasis"><em>template</em></span>,
|
||||
so why haven't we been using any template parameters?</b></span><br> <br>
|
||||
<tt class="literal">handle</tt> has a single template parameter specifying the
|
||||
type of the managed object. This type is <tt class="literal">PyObject</tt> 99%
|
||||
of the time, so the parameter was defaulted to <tt class="literal">PyObject</tt>
|
||||
for convenience. Therefore we can use the shorthand <tt class="literal">handle<></tt>
|
||||
instead of the longer, but equivalent, <tt class="literal">handle<PyObject></tt>.
|
||||
</p>
|
||||
<a name="using_the_interpreter.running_python_code"></a><h2>
|
||||
<a name="id463241"></a>
|
||||
Running Python code
|
||||
</h2>
|
||||
<p>
|
||||
To run Python code from C++ there is a family of functions in the API starting
|
||||
with the PyRun prefix. You can find the full list of these functions <a href="http://www.python.org/doc/current/api/veryhigh.html" target="_top">here</a>. They
|
||||
all work similarly so we will look at only one of them, namely:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">PyObject</span><span class="special">*</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span><span class="keyword">char</span> <span class="special">*</span><span class="identifier">str</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">start</span><span class="special">,</span> <span class="identifier">PyObject</span> <span class="special">*</span><span class="identifier">globals</span><span class="special">,</span> <span class="identifier">PyObject</span> <span class="special">*</span><span class="identifier">locals</span><span class="special">)</span>
|
||||
</pre>
|
||||
<p>
|
||||
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
|
||||
takes the code to execute as a null-terminated (C-style) string in its <tt class="literal">str</tt>
|
||||
parameter. The function returns a new reference to a Python object. Which
|
||||
object is returned depends on the <tt class="literal">start</tt> paramater.
|
||||
</p>
|
||||
<p>
|
||||
The <tt class="literal">start</tt> parameter is the start symbol from the Python
|
||||
grammar to use for interpreting the code. The possible values are:
|
||||
</p>
|
||||
<div class="informaltable">
|
||||
<h4>
|
||||
<a name="id463420"></a>
|
||||
<span class="table-title">Start symbols</span>
|
||||
</h4>
|
||||
<table class="table">
|
||||
<colgroup>
|
||||
<col>
|
||||
<col>
|
||||
</colgroup>
|
||||
<thead><tr>
|
||||
<th><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a></th>
|
||||
<th>for
|
||||
interpreting isolated expressions</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a></td>
|
||||
<td>for
|
||||
interpreting sequences of statements</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-60" target="_top">Py_single_input</a></td>
|
||||
<td>for
|
||||
interpreting a single statement</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p>
|
||||
When using <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>,
|
||||
the input string must contain a single expression and its result is returned.
|
||||
When using <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a>,
|
||||
the string can contain an abitrary number of statements and None is returned.
|
||||
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-60" target="_top">Py_single_input</a>
|
||||
works in the same way as <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a>
|
||||
but only accepts a single statement.
|
||||
</p>
|
||||
<p>
|
||||
Lastly, 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>
|
||||
We have already seen how to get the <tt class="literal"><span class="underline">_main</span>_</tt>
|
||||
module's namespace so let's run some Python code in it:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">main_module</span><span class="special">((</span>
|
||||
<span class="identifier">handle</span><span class="special"><>(</span><span class="identifier">borrowed</span><span class="special">(</span><a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a><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">handle</span><span class="special"><></span> <span class="identifier">ignored</span><span class="special">((</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><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> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a>
|
||||
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span>
|
||||
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">())</span>
|
||||
<span class="special">));</span>
|
||||
</pre>
|
||||
<p>
|
||||
Because the Python/C API doesn't know anything about <tt class="literal">object</tt>s,
|
||||
we used the object's <tt class="literal">ptr</tt> member function to retrieve the
|
||||
<tt class="literal">PyObject*</tt>.
|
||||
</p>
|
||||
<p>
|
||||
This should create a file called 'hello.txt' in the current directory containing
|
||||
a phrase that is well-known in programming circles.
|
||||
</p>
|
||||
<p class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Note</b></span> that we wrap
|
||||
the return value of <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
|
||||
in a (nameless) <tt class="literal">handle</tt> even though we are not interested
|
||||
in it. If we didn't do this, the the returned object would be kept alive
|
||||
unnecessarily. Unless you want to be a Dr. Frankenstein, always wrap <tt class="literal">PyObject*</tt>s
|
||||
in <tt class="literal">handle</tt>s.
|
||||
</p>
|
||||
<a name="using_the_interpreter.beyond_handles"></a><h2>
|
||||
<a name="id463926"></a>
|
||||
Beyond handles
|
||||
</h2>
|
||||
<p>
|
||||
It's nice that <tt class="literal">handle</tt> manages the reference counting details
|
||||
for us, but other than that it doesn't do much. Often we'd like to have a
|
||||
more useful class to manipulate Python objects. But we have already seen
|
||||
such a class above, and in the <a href="object.html" target="_top">previous section</a>:
|
||||
the aptly named <tt class="literal">object</tt> class and it's 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">handle</span><span class="special"><>(</span><span class="identifier">borrowed</span><span class="special">(</span><a href="http://www.python.org/doc/current/api/importing.html#l2h-125" target="_top">PyImport_AddModule</a><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">handle</span><span class="special"><></span> <span class="identifier">ignored</span><span class="special">((</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span>
|
||||
|
||||
<span class="string">"result = 5 ** 2"</span>
|
||||
|
||||
<span class="special">,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-59" target="_top">Py_file_input</a>
|
||||
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span>
|
||||
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">())</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 let <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
|
||||
return the result directly with <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">object</span> <span class="identifier">result</span><span class="special">((</span><span class="identifier">handle</span><span class="special"><>(</span>
|
||||
<a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span><span class="string">"5 ** 2"</span>
|
||||
<span class="special">,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>
|
||||
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span>
|
||||
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()))</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>
|
||||
<p class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Note</b></span> that <tt class="literal">object</tt>'s
|
||||
member function to return the wrapped <tt class="literal">PyObject*</tt> is called
|
||||
<tt class="literal">ptr</tt> instead of <tt class="literal">get</tt>. This makes sense
|
||||
if you take into account the different functions that <tt class="literal">object</tt>
|
||||
and <tt class="literal">handle</tt> perform.
|
||||
</p>
|
||||
<a name="using_the_interpreter.exception_handling"></a><h2>
|
||||
<a name="id464549"></a>
|
||||
Exception handling
|
||||
</h2>
|
||||
<p>
|
||||
If an exception occurs in the execution of some Python code, the <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a>
|
||||
function returns a null pointer. Constructing a <tt class="literal">handle</tt>
|
||||
out of this null pointer throws <a href="../../../../v2/errors.html#error_already_set-spec" target="_top">error_already_set</a>,
|
||||
so basically, the Python exception is automatically translated into a C++
|
||||
exception when using <tt class="literal">handle</tt>:
|
||||
</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">handle</span><span class="special"><>(</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span>
|
||||
<span class="string">"5/0"</span>
|
||||
<span class="special">,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>
|
||||
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span>
|
||||
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()))</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="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="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>
|
||||
<p>
|
||||
If you'd rather not have <tt class="literal">handle</tt> throw a C++ exception
|
||||
when it is constructed, you can use the <a href="../../../../v2/handle.html#allow_null-spec" target="_top">allow_null</a>
|
||||
function in the same way you'd use borrowed:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">handle</span><span class="special"><></span> <span class="identifier">result</span><span class="special">((</span><span class="identifier">allow_null</span><span class="special">(</span><a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-55" target="_top">PyRun_String</a><span class="special">(</span>
|
||||
<span class="string">"5/0"</span>
|
||||
<span class="special">,</span> <a href="http://www.python.org/doc/current/api/veryhigh.html#l2h-58" target="_top">Py_eval_input</a>
|
||||
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()</span>
|
||||
<span class="special">,</span> <span class="identifier">main_namespace</span><span class="special">.</span><span class="identifier">ptr</span><span class="special">()))));</span>
|
||||
|
||||
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">result</span><span class="special">)</span>
|
||||
<span class="comment">// Python exception occurred
|
||||
</span><span class="keyword">else</span>
|
||||
<span class="comment">// everything went okay, it's safe to use the result
|
||||
</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"><small>Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams</small></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="object.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="iterators.html"><img src="../images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
63
doc/tutorial/doc/html/python/exception.html
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) -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title> Exception Translation</title>
|
||||
<link rel="stylesheet" href="../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%">
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="iterators.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="techniques.html"><img src="../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"><small>Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams</small></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="iterators.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="techniques.html"><img src="../images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
609
doc/tutorial/doc/html/python/exposing.html
Normal file
@@ -0,0 +1,609 @@
|
||||
<!-- 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">
|
||||
<title> Exposing Classes</title>
|
||||
<link rel="stylesheet" href="../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%">
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="hello.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="functions.html"><img src="../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 shall 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 shall 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 shall 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>
|
||||
<p class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span><br>
|
||||
<br> If you are using Microsoft Visual C++ 6 or 7, you have to write <tt class="computeroutput"><span class="identifier">f</span></tt> as:<br> <br> <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>
|
||||
<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>
|
||||
<p class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>member function and methods</b></span><br>
|
||||
<br> 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>
|
||||
</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>
|
||||
<p class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/alert.png" alt="alert"></span> <span class="bold"><b>MSVC6/7 Workaround</b></span><br>
|
||||
<br> 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:<br> <br> <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>
|
||||
<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="id453009"></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="id453761"></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>
|
||||
<p class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> 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>
|
||||
</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"><small>Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams</small></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="hello.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="functions.html"><img src="../images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
606
doc/tutorial/doc/html/python/functions.html
Normal file
@@ -0,0 +1,606 @@
|
||||
<!-- 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">
|
||||
<title>Functions</title>
|
||||
<link rel="stylesheet" href="../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%">
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exposing.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="object.html"><img src="../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 shall see some facilities to make exposing C++ functions to Python safe
|
||||
from potential pifalls such as dangling pointers and references. We shall 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>
|
||||
<span class="emphasis"><em>Read on...</em></span>
|
||||
</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="identifier">x</span> <span class="identifier">refers</span> <span class="identifier">to</span> <span class="identifier">some</span> <span class="identifier">C</span><span class="special">++</span> <span class="identifier">X</span>
|
||||
<span class="special">>>></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="identifier">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="identifier">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="identifier">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="identifier">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="id455614"></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><br> Ties lifetimes
|
||||
of the arguments
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>with_custodian_and_ward_postcall</b></span><br>
|
||||
Ties lifetimes of the arguments and results
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>return_internal_reference</b></span><br> 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><br>
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>reference_existing_object</b></span><br> naive
|
||||
(dangerous) approach
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>copy_const_reference</b></span><br> Boost.Python
|
||||
v1 approach
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>copy_non_const_reference</b></span><br>
|
||||
</li>
|
||||
<li>
|
||||
<span class="bold"><b>manage_new_object</b></span><br> Adopt a pointer
|
||||
and hold the instance
|
||||
</li>
|
||||
</ul></div>
|
||||
<p class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/smiley.png" alt="smiley"></span> <span class="bold"><b>Remember the Zen, Luke:</b></span><br>
|
||||
<br> "Explicit is better than implicit"<br> "In the face
|
||||
of ambiguity, refuse the temptation to guess"<br>
|
||||
</p>
|
||||
</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 shall 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="id457647"></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="id457963"></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="id458323"></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="id459095"></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"><small>Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams</small></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exposing.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="object.html"><img src="../images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
290
doc/tutorial/doc/html/python/hello.html
Normal file
@@ -0,0 +1,290 @@
|
||||
<!-- 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">
|
||||
<title> Building Hello World</title>
|
||||
<link rel="stylesheet" href="../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%">
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../index.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="exposing.html"><img src="../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="id377427"></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 shall outline the steps
|
||||
necessary to achieve that. We shall use the build tool that comes bundled with
|
||||
every boost distribution: <span class="bold"><b>bjam</b></span>.
|
||||
</p>
|
||||
<p class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>Building without bjam</b></span><br>
|
||||
<br> 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>.<br>
|
||||
<br> 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>
|
||||
<p>
|
||||
We shall 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 two
|
||||
DLLs:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
boost_python.dll
|
||||
</li>
|
||||
<li>
|
||||
hello.pyd
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
if you are on Windows, and
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
libboost_python.so
|
||||
</li>
|
||||
<li>
|
||||
hello.so
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
if you are on Unix.
|
||||
</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>
|
||||
Jamfile
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
The <tt class="literal">hello.cpp</tt> file is our C++ hello world example. The
|
||||
<tt class="literal">Jamfile</tt> is a minimalist <span class="emphasis"><em>bjam</em></span> script
|
||||
that builds the DLLs for us.
|
||||
</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="id377613"></a>
|
||||
Let's Jam!
|
||||
</h2>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/jam.png" alt="jam"></span>
|
||||
</p>
|
||||
<p>
|
||||
Here is our minimalist Jamfile:
|
||||
</p>
|
||||
<pre class="programlisting"># This is the top of our own project tree
|
||||
project-root ;
|
||||
|
||||
import python ;
|
||||
|
||||
extension hello # Declare a Python extension called hello
|
||||
: hello.cpp # source
|
||||
# requirements and dependencies for Boost.Python extensions
|
||||
<template>@boost/libs/python/build/extension
|
||||
;
|
||||
</pre>
|
||||
<p>
|
||||
First, we need to specify our location. You may place your project anywhere.
|
||||
<tt class="literal">project-root</tt> allows you to do that.
|
||||
</p>
|
||||
<pre class="programlisting">project-root ;
|
||||
</pre>
|
||||
<p>
|
||||
By doing so, you'll need a Jamrules file. Simply copy the one in the <a href="../../../../../example/tutorial/Jamrules" target="_top">example/tutorial directory</a>
|
||||
and tweak the <tt class="literal">path-global BOOST_ROOT</tt> to where your boost
|
||||
root directory is. The file has <a href="../../../../../example/tutorial/Jamrules" target="_top">detailed
|
||||
instructions</a> you can follow.
|
||||
</p>
|
||||
<p>
|
||||
Then we will import the definitions needed by Python modules:
|
||||
</p>
|
||||
<pre class="programlisting">import python ;
|
||||
</pre>
|
||||
<p>
|
||||
Finally we declare our <tt class="literal">hello</tt> extension:
|
||||
</p>
|
||||
<pre class="programlisting">extension hello # Declare a Python extension called hello
|
||||
: hello.cpp # source
|
||||
|
||||
# requirements and dependencies for Boost.Python extensions
|
||||
<template>@boost/libs/python/build/extension
|
||||
;
|
||||
</pre>
|
||||
<p>
|
||||
The last part tells BJam that we are depending on the Boost Python Library.
|
||||
</p>
|
||||
<a name="hello.running_bjam"></a><h2>
|
||||
<a name="id377751"></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>
|
||||
Start it up.
|
||||
</p></blockquote></div>
|
||||
<p>
|
||||
Make sure that the environment is set so that we can invoke the C++ compiler.
|
||||
With MSVC, that would mean running the <tt class="literal">Vcvars32.bat</tt> batch
|
||||
file. For instance:
|
||||
</p>
|
||||
<pre class="programlisting">C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\vsvars32.bat
|
||||
</pre>
|
||||
<p>
|
||||
Some environment variables will have to be setup for proper building of our
|
||||
Python modules. Example:
|
||||
</p>
|
||||
<pre class="programlisting">set PYTHON_ROOT=c:/dev/tools/python
|
||||
set PYTHON_VERSION=2.2
|
||||
</pre>
|
||||
<p>
|
||||
The above assumes that the Python installation is in <tt class="literal">c:/dev/tools/python</tt>
|
||||
and that we are using Python version 2.2. You'll have to tweak these appropriately.
|
||||
</p>
|
||||
<p class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/tip.png" alt="tip"></span> Be sure not to include a third number, e.g. <span class="bold"><b>not</b></span> "2.2.1", even if that's the version you
|
||||
have.
|
||||
</p>
|
||||
<p>
|
||||
Take note that you may also do that through the Jamrules file we put in our
|
||||
project as detailed above. The file has <a href="../../../../../example/tutorial/Jamrules" target="_top">detailed
|
||||
instructions</a> you can follow.
|
||||
</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">"Jamfile"</tt>
|
||||
is situated.
|
||||
</p>
|
||||
<p>
|
||||
Finally:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
<span class="identifier">bjam</span> <span class="special">-</span><span class="identifier">sTOOLS</span><span class="special">=</span><span class="identifier">vc</span><span class="special">-</span><span class="number">7</span><span class="identifier">_1</span>
|
||||
</pre>
|
||||
<p>
|
||||
We are again assuming that we are using Microsoft Visual C++ version 7.1. If
|
||||
not, then you will have to specify the appropriate tool. See <a href="../../../../../../../tools/build/index.html" target="_top">Building
|
||||
Boost Libraries</a> for further details.
|
||||
</p>
|
||||
<p>
|
||||
It should be building now:
|
||||
</p>
|
||||
<pre class="programlisting">cd C:\dev\boost\libs\python\example\tutorial
|
||||
bjam -sTOOLS=msvc
|
||||
...patience...
|
||||
...found 1703 targets...
|
||||
...updating 40 targets...
|
||||
</pre>
|
||||
<p>
|
||||
And so on... Finally:
|
||||
</p>
|
||||
<pre class="programlisting">Creating library bin\boost\libs\python\build\boost_python.dll\vc-7_1\debug\th
|
||||
reading-multi\boost_python.lib and object bin\boost\libs\python\build\boost_pyth
|
||||
on.dll\vc-7_1\debug\threading-multi\boost_python.exp
|
||||
vc-C++ bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.obj
|
||||
hello.cpp
|
||||
vc-Link bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.pyd bin\tutori
|
||||
al\hello.pyd\vc-7_1\debug\threading-multi\hello.lib
|
||||
Creating library bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.li
|
||||
b and object bin\tutorial\hello.pyd\vc-7_1\debug\threading-multi\hello.exp
|
||||
...updated 31 targets...
|
||||
</pre>
|
||||
<p>
|
||||
If all is well, you should now have:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
boost_python.dll
|
||||
</li>
|
||||
<li>
|
||||
hello.pyd
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
if you are on Windows, and
|
||||
</p>
|
||||
<div class="itemizedlist"><ul type="disc">
|
||||
<li>
|
||||
libboost_python.so
|
||||
</li>
|
||||
<li>
|
||||
hello.so
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
if you are on Unix.
|
||||
</p>
|
||||
<p>
|
||||
<tt class="literal">boost_python.dll</tt> and <tt class="literal">hello.pyd</tt> can be
|
||||
found somewhere in your project's <tt class="literal">bin</tt> directory. After a
|
||||
successful build, you make it possible for the system to find boost_python.dll
|
||||
or libboost_python.so (usually done with LD_LIBRARY_PATH, DYLD_LIBRARY_PATH,
|
||||
or some other variable on *nix and with PATH on Windows) and for Python to
|
||||
find the hello module (Done with PYTHONPATH on all systems.)
|
||||
</p>
|
||||
<p>
|
||||
You may now fire up Python and run our hello module:
|
||||
</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="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>
|
||||
<span class="bold"><b>There you go... Have fun!</b></span>
|
||||
</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"><small>Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams</small></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../index.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="exposing.html"><img src="../images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
204
doc/tutorial/doc/html/python/iterators.html
Normal file
@@ -0,0 +1,204 @@
|
||||
<!-- 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">
|
||||
<title>Iterators</title>
|
||||
<link rel="stylesheet" href="../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%">
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="embedding.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="exception.html"><img src="../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"><small>Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams</small></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="embedding.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="exception.html"><img src="../images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
345
doc/tutorial/doc/html/python/object.html
Normal file
@@ -0,0 +1,345 @@
|
||||
<!-- 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">
|
||||
<title> Object Interface</title>
|
||||
<link rel="stylesheet" href="../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%">
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="functions.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="embedding.html"><img src="../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 shall 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>
|
||||
<p class="blurb">
|
||||
<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>
|
||||
<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="id461067"></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>
|
||||
<p class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> <span class="bold"><b>what is a scope?</b></span><br>
|
||||
<br> 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>
|
||||
<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"><small>Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams</small></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="functions.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="embedding.html"><img src="../images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
453
doc/tutorial/doc/html/python/techniques.html
Normal file
@@ -0,0 +1,453 @@
|
||||
<!-- 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">
|
||||
<title> General Techniques</title>
|
||||
<link rel="stylesheet" href="../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%">
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.htm">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="../../../../../../../people/people.htm">People</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/faq.htm">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exception.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../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>
|
||||
<p class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> 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>
|
||||
<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
|
||||
_core.pyd
|
||||
filters/
|
||||
__init__.py
|
||||
_filters.pyd
|
||||
io/
|
||||
__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>
|
||||
<p class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> 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>
|
||||
<p class="blurb">
|
||||
<span class="inlinemediaobject"><img src="../images/note.png" alt="note"></span> 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>
|
||||
</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"><small>Copyright © 2002-2005 Joel
|
||||
de Guzman, David Abrahams</small></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exception.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,98 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Inheritance</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="class_properties.html">
|
||||
<link rel="next" href="class_virtual_functions.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Inheritance</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_properties.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="class_virtual_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<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>
|
||||
<code><pre>
|
||||
<span class=keyword>struct </span><span class=identifier>Base </span><span class=special>{ </span><span class=keyword>virtual </span><span class=special>~</span><span class=identifier>Base</span><span class=special>(); </span><span class=special>};
|
||||
</span><span class=keyword>struct </span><span class=identifier>Derived </span><span class=special>: </span><span class=identifier>Base </span><span class=special>{};
|
||||
</span></pre></code>
|
||||
<p>
|
||||
And a set of C++ functions operating on <tt>Base</tt> and <tt>Derived</tt> object
|
||||
instances:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>void </span><span class=identifier>b</span><span class=special>(</span><span class=identifier>Base</span><span class=special>*);
|
||||
</span><span class=keyword>void </span><span class=identifier>d</span><span class=special>(</span><span class=identifier>Derived</span><span class=special>*);
|
||||
</span><span class=identifier>Base</span><span class=special>* </span><span class=identifier>factory</span><span class=special>() </span><span class=special>{ </span><span class=keyword>return </span><span class=keyword>new </span><span class=identifier>Derived</span><span class=special>; </span><span class=special>}
|
||||
</span></pre></code>
|
||||
<p>
|
||||
We've seen how we can wrap the base class <tt>Base</tt>:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>class_</span><span class=special><</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></code>
|
||||
<p>
|
||||
Now we can inform Boost.Python of the inheritance relationship between
|
||||
<tt>Derived</tt> and its base class <tt>Base</tt>. Thus:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>class_</span><span class=special><</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></code>
|
||||
<p>
|
||||
Doing so, we get some things for free:</p>
|
||||
<ol><li>Derived automatically inherits all of Base's Python methods (wrapped C++ member functions)</li><li><b>If</b> Base is polymorphic, <tt>Derived</tt> objects which have been passed to Python via a pointer or reference to <tt>Base</tt> can be passed where a pointer or reference to <tt>Derived</tt> is expected.</li></ol><p>
|
||||
Now, we shall expose the C++ free functions <tt>b</tt> and <tt>d</tt> and <tt>factory</tt>:</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
Note that free function <tt>factory</tt> is being used to generate new
|
||||
instances of class <tt>Derived</tt>. In such cases, we use
|
||||
<tt>return_value_policy<manage_new_object></tt> to instruct Python to adopt
|
||||
the pointer to <tt>Base</tt> and hold the instance in a new Python <tt>Base</tt>
|
||||
object until the the Python object is destroyed. We shall see more of
|
||||
Boost.Python <a href="call_policies.html">
|
||||
call policies</a> later.</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="class_properties.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="class_virtual_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,101 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Iterators</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="enums.html">
|
||||
<link rel="next" href="exception_translation.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Iterators</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="enums.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="exception_translation.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
In C++, and STL in particular, we see iterators everywhere. Python also has
|
||||
iterators, but these are two very different beasts.</p>
|
||||
<p>
|
||||
<b>C++ iterators:</b></p>
|
||||
<ul><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><p>
|
||||
<b>Python Iterators:</b></p>
|
||||
<ul><li>1 category (forward)</li><li>1 operation category (next())</li><li>Raises StopIteration exception at end</li></ul><p>
|
||||
The typical Python iteration protocol: <tt><b>for y in x...</b></tt> is as follows:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>iter </span><span class=special>= </span><span class=identifier>x</span><span class=special>.</span><span class=identifier>__iter__</span><span class=special>() </span>#<span class=identifier>get </span><span class=identifier>iterator
|
||||
</span><span class=keyword>try</span><span class=special>:
|
||||
</span><span class=keyword>while </span><span class=number>1</span><span class=special>:
|
||||
</span><span class=identifier>y </span><span class=special>= </span><span class=identifier>iter</span><span class=special>.</span><span class=identifier>next</span><span class=special>() </span>#<span class=identifier>get </span><span class=identifier>each </span><span class=identifier>item
|
||||
</span><span class=special>... </span>#<span class=identifier>process </span><span class=identifier>y
|
||||
</span><span class=identifier>except </span><span class=identifier>StopIteration</span><span class=special>: </span><span class=identifier>pass </span>#<span class=identifier>iterator </span><span class=identifier>exhausted
|
||||
</span></pre></code>
|
||||
<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 __iter__ function from C++ iterators that is compatible
|
||||
with the Python iteration protocol. For example:</p>
|
||||
<code><pre>
|
||||
<span class=identifier>object </span><span class=identifier>get_iterator </span><span class=special>= </span><span class=identifier>iterator</span><span class=special><</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></code>
|
||||
<p>
|
||||
Or for use in class_<>:</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<p>
|
||||
<b>range</b></p>
|
||||
<p>
|
||||
We can create a Python savvy iterator using the range function:</p>
|
||||
<ul><li>range(start, finish)</li><li>range<Policies,Target>(start, finish)</li></ul><p>
|
||||
Here, start/finish may be one of:</p>
|
||||
<ul><li>member data pointers</li><li>member function pointers</li><li>adaptable function object (use Target parameter)</li></ul><p>
|
||||
<b>iterator</b></p>
|
||||
<ul><li>iterator<T, Policies>()</li></ul><p>
|
||||
Given a container <tt>T</tt>, iterator is a shortcut that simply calls <tt>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>
|
||||
<code><pre>
|
||||
<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=identifier>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=identifier>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></code>
|
||||
<p>
|
||||
Now, our C++ Wrapper:</p>
|
||||
<code><pre>
|
||||
<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></code>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="enums.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="exception_translation.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,54 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Object Interface</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="prev" href="default_arguments.html">
|
||||
<link rel="next" href="basic_interface.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Object Interface</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="default_arguments.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="basic_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<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>object</tt>. We shall 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>object</tt>s are as close as possible to Python. This
|
||||
should minimize the learning curve significantly.</p>
|
||||
<p>
|
||||
<img src="theme/python.png"></img></p>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><a href="default_arguments.html"><img src="theme/l_arr.gif" border="0"></a></td>
|
||||
<td width="20"><a href="basic_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,79 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>QuickStart</title>
|
||||
<link rel="stylesheet" href="theme/style.css" type="text/css">
|
||||
<link rel="next" href="building_hello_world.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>QuickStart</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><img src="theme/l_arr_disabled.gif" border="0"></td>
|
||||
<td width="20"><a href="building_hello_world.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<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="hello_world"></a><h2>Hello World</h2><p>
|
||||
Following C/C++ tradition, let's start with the "hello, world". A C++
|
||||
Function:</p>
|
||||
<code><pre>
|
||||
<span class=keyword>char </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>greet</span><span class=special>()
|
||||
</span><span class=special>{
|
||||
</span><span class=keyword>return </span><span class=string>"hello, world"</span><span class=special>;
|
||||
</span><span class=special>}
|
||||
</span></pre></code>
|
||||
<p>
|
||||
can be exposed to Python by writing a Boost.Python wrapper:</p>
|
||||
<code><pre>
|
||||
<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>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></code>
|
||||
<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>
|
||||
<code><pre>
|
||||
<span class=special>>>> </span><span class=identifier>import </span><span class=identifier>hello
|
||||
</span><span class=special>>>> </span><span class=identifier>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></code>
|
||||
<blockquote><p><i><b>Next stop... Building your Hello World module from start to finish...</b></i></p></blockquote><table border="0">
|
||||
<tr>
|
||||
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
|
||||
<td width="30"><img src="theme/l_arr_disabled.gif" border="0"></td>
|
||||
<td width="20"><a href="building_hello_world.html"><img src="theme/r_arr.gif" border="0"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</html>
|
||||
BIN
doc/tutorial/doc/theme/c++boost.gif
vendored
|
Before Width: | Height: | Size: 8.6 KiB |
BIN
doc/tutorial/doc/theme/lens.gif
vendored
|
Before Width: | Height: | Size: 897 B |
2150
doc/tutorial/doc/tutorial.qbk
Normal file
@@ -1,126 +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>
|
||||
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
|
||||
<title>Boost Python Tutorial</title>
|
||||
<link rel="stylesheet" href="doc/theme/style.css" type="text/css">
|
||||
<link rel="next" href="quickstart.html">
|
||||
</head>
|
||||
<body>
|
||||
<table width="100%" height="48" border="0" cellspacing="2">
|
||||
<tr>
|
||||
<td><img src="doc/theme/c%2B%2Bboost.gif">
|
||||
</td>
|
||||
<td width="85%">
|
||||
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Boost Python Tutorial</b></font>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<table width="80%" border="0" align="center">
|
||||
<tr>
|
||||
<td class="toc_title">Table of contents</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0">
|
||||
<a href="doc/quickstart.html">QuickStart</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0">
|
||||
<a href="doc/building_hello_world.html">Building Hello World</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0">
|
||||
<a href="doc/exposing_classes.html">Exposing Classes</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1">
|
||||
<a href="doc/constructors.html">Constructors</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1">
|
||||
<a href="doc/class_data_members.html">Class Data Members</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1">
|
||||
<a href="doc/class_properties.html">Class Properties</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1">
|
||||
<a href="doc/inheritance.html">Inheritance</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1">
|
||||
<a href="doc/class_virtual_functions.html">Class Virtual Functions</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1">
|
||||
<a href="doc/class_operators_special_functions.html">Class Operators/Special Functions</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0">
|
||||
<a href="doc/functions.html">Functions</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1">
|
||||
<a href="doc/call_policies.html">Call Policies</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1">
|
||||
<a href="doc/default_arguments.html">Default Arguments</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0">
|
||||
<a href="doc/object_interface.html">Object Interface</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1">
|
||||
<a href="doc/basic_interface.html">Basic Interface</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1">
|
||||
<a href="doc/derived_object_types.html">Derived Object types</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1">
|
||||
<a href="doc/extracting_c___objects.html">Extracting C++ objects</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L1">
|
||||
<a href="doc/enums.html">Enums</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0">
|
||||
<a href="doc/iterators.html">Iterators</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="toc_cells_L0">
|
||||
<a href="doc/exception_translation.html">Exception Translation</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<hr size="1"><p class="copyright">Copyright © 2002 David Abrahams<br>Copyright © 2002 Joel de Guzman<br><br>
|
||||
<font size="2">Permission to copy, use, modify, sell and distribute this document
|
||||
is granted provided this copyright notice appears in all copies. This document
|
||||
is provided "as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose. </font> </p>
|
||||
</body>
|
||||
</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,3 +1,6 @@
|
||||
<!-- 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">
|
||||
@@ -10,10 +13,10 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
|
||||
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
"C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">April 2002 Progress Report</h2>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -45,7 +48,7 @@ of work got done...
|
||||
<h3><a name="arity">Arbitrary Arity Support</a></h3>
|
||||
|
||||
I began using the <a
|
||||
href="../../../preprocessor/doc/index.htm">Boost.Preprocessor</a>
|
||||
href="../../../preprocessor/doc/index.html">Boost.Preprocessor</a>
|
||||
metaprogramming library to generate support for functions and member
|
||||
functions of arbitrary arity, which was, to say the least, quite an
|
||||
adventure. The feedback cycle resulting from my foray into
|
||||
@@ -154,10 +157,10 @@ documentation).
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
3 May, 2002
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
2002. </i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
<!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">
|
||||
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
|
||||
|
||||
<title>Boost.Python - CallPolicies Concept</title>
|
||||
</head>
|
||||
@@ -16,11 +19,11 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">CallPolicies Concept</h2>
|
||||
</td>
|
||||
@@ -113,7 +116,7 @@
|
||||
"ResultConverter.html#ResultConverterGenerator-concept">ResultConverterGenerator</a>.</td>
|
||||
|
||||
<td>An MPL unary <a href=
|
||||
"../../../mpl/doc/paper/html/usage.html#metafunctions.classes">Metafunction
|
||||
"../../../mpl/doc/refmanual/metafunction-class.html">Metafunction
|
||||
Class</a> used produce the "preliminary" result object.</td>
|
||||
</tr>
|
||||
|
||||
@@ -136,12 +139,12 @@
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
19 May, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
"../../../../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
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<!-- 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">
|
||||
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
|
||||
<title>Boost.Python - Dereferenceable Concept</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
@@ -9,10 +12,10 @@
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
<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>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">Dereferenceable Concept</h2>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -28,35 +31,40 @@
|
||||
|
||||
<h2><a name="introduction"></a>Introduction</h2>
|
||||
|
||||
<p>Instances of a dereferenceable type can be used like a pointer to access an lvalue.
|
||||
<p>Instances of a Dereferenceable type can be used like a pointer to access an lvalue.
|
||||
|
||||
<h2><a name="concept-requirements"></a>Concept Requirements</h2>
|
||||
<h3><a name="Dereferenceable-concept"></a>Dereferenceable Concept</h3>
|
||||
|
||||
<p>In the table below, <code><b>x</b></code> denotes an object whose
|
||||
type is a model of Dereferenceable.
|
||||
<p>In the table below, <code><b>T</b></code> is a model of
|
||||
Dereferenceable, and <code><b>x</b></code> denotes an object of
|
||||
type <code>T</code>. In addition, all pointers are Dereferenceable.
|
||||
|
||||
<table summary="Dereferenceable expressions" border="1" cellpadding="5">
|
||||
|
||||
<tr>
|
||||
<td><b>Expression</b></td>
|
||||
<td><b>Requirements</b></td>
|
||||
<td><b>Result</b></td>
|
||||
<td><b>Operational Semantics</b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign="top"><code>*x</code></td>
|
||||
<td>An lvalue
|
||||
<td><code>get_pointer(x)</code></td>
|
||||
<td>convertible to <code><a href="pointee.html#pointee-spec">pointee</a><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 -->
|
||||
10 May, 2002
|
||||
18 December, 2003
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
Abrahams</a> 2002-2003. </i>
|
||||
|
||||
<p>Permission to copy, use, modify, sell
|
||||
and distribute this software is granted provided this copyright notice appears
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<!-- 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">
|
||||
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
|
||||
<title>Boost.Python - Extractor Concept</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
@@ -9,10 +12,10 @@
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
<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>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">Extractor Concept</h2>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -79,11 +82,11 @@ are layout-compatible with PyObject.
|
||||
<hr>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
22 May, 2002
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
Abrahams</a> 2002. </i>
|
||||
|
||||
<p>Permission to copy, use, modify, sell
|
||||
and distribute this software is granted provided this copyright notice appears
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<!-- 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">
|
||||
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
|
||||
<title>Boost.Python - Holder Concept</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
@@ -9,10 +12,10 @@
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
<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>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">HolderGenerator Concept</h2>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -57,11 +60,11 @@ type.
|
||||
<hr>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
20 May, 2002
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
Abrahams</a> 2002. </i>
|
||||
|
||||
<p>Permission to copy, use, modify, sell
|
||||
and distribute this software is granted provided this copyright notice appears
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
<!-- 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">
|
||||
@@ -10,10 +13,10 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
|
||||
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
"C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">June 2002 Progress Report</h2>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -217,10 +220,10 @@ you'll just have to wait till next month (hopefully the beginning).
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
19 July, 2002
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
2002. </i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
<!-- 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">
|
||||
@@ -10,10 +13,10 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
|
||||
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
"C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">March 2002 Progress Report</h2>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -225,10 +228,10 @@ worth doing anything about it.
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
1 April, 2002
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
2002. </i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
<!-- 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">
|
||||
@@ -10,10 +13,10 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
|
||||
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
"C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">May 2002 Progress Report</h2>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -54,7 +57,7 @@ focused on reducing the support burden. In recent weeks, responding to
|
||||
requests for support, espcially surrounding building the library, had
|
||||
begun to impede progress on development. There was a major push to
|
||||
release a stable 1.28.0 of Boost, including documentation of <a
|
||||
href="../../../../tools/build/index.html">Boost.Build</a> and specific
|
||||
href="../../../../tools/build/v1/build_system.htm">Boost.Build</a> and specific
|
||||
<a href="../building.html">instructions</a> for building Boost.Python
|
||||
v1. The documentation for Boost.Python v2 was also updated as
|
||||
described <a href="#documentation">here</a>.
|
||||
@@ -70,7 +73,7 @@ described <a href="#documentation">here</a>.
|
||||
Martin Casado which uncovered the key mechanism required to allow
|
||||
shared libraries to use functions from the Python executable. The
|
||||
current solution used in Boost.Build relies on a <a
|
||||
href="../../../../tools/build/gen_aix_import_file.py">Python
|
||||
href="../../../../tools/build/v1/gen_aix_import_file.py">Python
|
||||
Script</a> as part of the build process. This is not a problem for
|
||||
Boost.Python, as Python will be available. However, the commands
|
||||
issued by the script are so simple that a 100%-pure-Boost.Jam
|
||||
@@ -84,8 +87,7 @@ described <a href="#documentation">here</a>.
|
||||
|
||||
Support for exposing C++ operators and functions as the corresponding
|
||||
Python special methods was added. Thinking that the Boost.Python
|
||||
<a href="../special.html#numeric">v1 interface</a> was a little too
|
||||
esoteric (especially the use of
|
||||
v1 interface was a little too esoteric (especially the use of
|
||||
<code>left_operand<...>/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
|
||||
@@ -155,7 +157,7 @@ This forced the exposure of the <a
|
||||
href="http://www.python.org/2.2/descrintro.html#property"><code>property</code></a>
|
||||
interface used internally to implement the data member exposure
|
||||
facility described in <a
|
||||
href="Mar2002#data_members">March</a>. Properties are an
|
||||
href="Mar2002.html#data_members">March</a>. Properties are an
|
||||
incredibly useful idiom, so it's good to be able to provide them
|
||||
at little new development cost.
|
||||
|
||||
@@ -212,7 +214,7 @@ Major updates were made to the following pages:
|
||||
|
||||
<blockquote>
|
||||
<dl>
|
||||
<dt><a href="call.html">call.html</a><dd> <dt><a href="updated">updated</a><dd>
|
||||
<dt><a href="call.html">call.html</a><dd> <dt>updated<dd>
|
||||
<dt><a href="class.html">class.html</a><dd>
|
||||
<dt><a href="reference.html">reference.html</a><dd>
|
||||
</dl>
|
||||
@@ -300,10 +302,10 @@ to these issues will probably have to be formalized before long.
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
11 June, 2002
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
2002. </i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<!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=
|
||||
@@ -16,11 +19,11 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">ObjectWrapper and TypeWrapper Concepts</h2>
|
||||
</td>
|
||||
@@ -139,17 +142,12 @@ instances of the associated Python type will be considered a match.
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
30 Sept, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</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>
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<!-- 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">
|
||||
<link rel="stylesheet" type="text/css" href=../../../../boost.css>
|
||||
<title>Boost.Python - ResultConverter Concept</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
@@ -9,10 +12,10 @@
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277" alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
<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>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">ResultConverter Concept</h2>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -100,7 +103,7 @@ C++ function return type.
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
Abrahams</a> 2002. </i>
|
||||
|
||||
<p>Permission to copy, use, modify, sell
|
||||
and distribute this software is granted provided this copyright notice appears
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<!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=
|
||||
@@ -16,11 +19,11 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Acknowledgments</h2>
|
||||
</td>
|
||||
@@ -31,19 +34,57 @@
|
||||
<p><a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a> is
|
||||
the architect, designer, and implementor of <b>Boost.Python</b>.</p>
|
||||
|
||||
<p><a href="mailto:brett.calcott@paradise.net.nz">Brett Calcott</a>
|
||||
contributed and maintains the Visual Studio project files and
|
||||
documentation.</p>
|
||||
|
||||
<p><a href="mailto:Gottfried.Ganssauge-at-haufe.de">Gottfried
|
||||
Ganßauge</a> supplied support for opaque pointer conversions,
|
||||
complete with documentation and a regression test (and I didn't
|
||||
even have to ask him for those)!
|
||||
|
||||
<p>Joel de Guzman implemented the <a href="overloads.html">default
|
||||
argument support</a> and wrote the excellent tutorial documentation.</p>
|
||||
argument support</a> and wrote the excellent <a href=
|
||||
"../tutorial/index.html">tutorial documentation</a>.</p>
|
||||
|
||||
<p><a href="../../../../people/ralf_w_grosse_kunstleve.htm">Ralf W.
|
||||
Grosse-Kunstleve</a> implemented the <a href="pickle.html">pickle
|
||||
support</a>, and has enthusiastically supported the library since its
|
||||
birth, contributing to design decisions and providing invaluable
|
||||
real-world insight into user requirements. Ralf has written some
|
||||
extensions for converting C++ containers that I hope will be incorporated
|
||||
into the library soon. He also implemented the cross-module support in
|
||||
the first version of Boost.Python. More importantly, Ralf makes sure
|
||||
nobody forgets the near-perfect synergy of C++ and Python for solving the
|
||||
problems of large-scale software construction.</p>
|
||||
real-world insight into user requirements. Ralf has written some <a href=
|
||||
"faq.html#question2">extensions</a> for converting C++ containers that I
|
||||
hope will be incorporated into the library soon. He also implemented the
|
||||
cross-module support in the first version of Boost.Python. More
|
||||
importantly, Ralf makes sure nobody forgets the near-perfect synergy of
|
||||
C++ and Python for solving the problems of large-scale software
|
||||
construction.</p>
|
||||
|
||||
<p><a href="../../../../people/aleksey_gurtovoy.htm">Aleksey Gurtovoy</a>
|
||||
wrote an incredible C++ <a href="http://www.mywikinet.com/mpl">Template
|
||||
Metaprogramming Library</a> which allows Boost.Python to perform much of
|
||||
its compile-time magic. In addition, Aleksey very generously contributed
|
||||
his time and deep knowledge of the quirks of various buggy compilers to
|
||||
help us get around problems at crucial moments.</p>
|
||||
|
||||
<p><a href="../../../../people/paul_mensonides.htm">Paul Mensonides</a>,
|
||||
building on the work <a href="../../../../people/vesa_karvonen.htm">Vesa
|
||||
Karvonen</a>, wrote a similarly amazing <a href=
|
||||
"../../../preprocessor/doc/index.html">Preprocessor Metaprogramming
|
||||
Library</a>, and generously contributed the time and expertise to get it
|
||||
working in the Boost.Python library, rewriting much of Boost.Python to
|
||||
use the new preproccessor metaprogramming constructs and helping us to
|
||||
work around buggy and slow C++ preprocessors.</p>
|
||||
|
||||
<p><a href="mailto:nicodemus-at-globalite.com.br">Bruno da Silva de
|
||||
Oliveira</a> contributed the ingenious <a
|
||||
href="../../pyste/index.html">Pyste</a> ("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
|
||||
@@ -53,9 +94,6 @@
|
||||
definition syntax. Pearu Pearson wrote some of the test cases that are in
|
||||
the current test suite.</p>
|
||||
|
||||
<p>Martin Casado solved some sticky problems which allow us to build the
|
||||
Boost.Python shared library for AIX's crazy dynamic linking model.</p>
|
||||
|
||||
<p>The development of this version of Boost.Python was funded in part by
|
||||
the <a href="http://www.llnl.gov/">Lawrence Livermore National
|
||||
Laboratories</a> and by the <a href="http://cci.lbl.gov/">Computational
|
||||
@@ -63,8 +101,21 @@
|
||||
Laboratories.</p>
|
||||
|
||||
<p><a href="http://kogs-www.informatik.uni-hamburg.de/~koethe/">Ullrich
|
||||
Koethe</a> provided the implementation of inheritance and special
|
||||
method/operator support in the first version of Boost.Python.</p>
|
||||
Koethe</a> had independently developed a similar system. When he
|
||||
discovered Boost.Python v1, he generously contributed countless hours of
|
||||
coding and much insight into improving it. He is responsible for an early
|
||||
version of the support for function overloading and wrote the support for
|
||||
reflecting C++ inheritance relationships. He has helped to improve
|
||||
error-reporting from both Python and C++ (we hope to do as well in v2
|
||||
again soon), and has designed the original support for exposing numeric
|
||||
operators, including a way to avoid explicit coercion by means of
|
||||
overloading.</p>
|
||||
|
||||
<p>The members of the boost mailing list and the Python community
|
||||
supplied invaluable early feedback. In particular, Ron Clarke, Mark
|
||||
Evans, Anton Gluck, Chuck Ingold, Prabhu Ramachandran, and Barry Scott
|
||||
took the brave step of trying to use Boost.Python while it was still in
|
||||
early stages of development.</p>
|
||||
|
||||
<p>The first version of Boost.Python would not have been possible without
|
||||
the support of Dragon Systems, which supported its development and
|
||||
@@ -73,13 +124,12 @@
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
08 October, 2002
|
||||
26 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
140
doc/v2/args.html
@@ -1,9 +1,12 @@
|
||||
<!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">
|
||||
"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">
|
||||
|
||||
@@ -16,11 +19,11 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/args.hpp></h2>
|
||||
</td>
|
||||
@@ -35,7 +38,31 @@
|
||||
|
||||
<dt><a href="#keyword-expression"><i>keyword-expressions</i></a></dt>
|
||||
|
||||
<dt><a href="#functions">Functions</a></dt>
|
||||
<dt><a href="#classes">Classes</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#arg-spec">class <code>arg</code></a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
<dt><a href="#arg-synopsis">class <code>arg</code>
|
||||
synopsis</a></dt>
|
||||
|
||||
<dt><a href="#arg-ctor">class <code>arg</code>
|
||||
constructor</a></dt>
|
||||
|
||||
<dt><a href="#arg-operator">class <code>arg</code> template
|
||||
<code>operator =</code></a></dt>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
|
||||
<dt><a href="#keyword-expression-operators"><i>Keyword-expression</i>
|
||||
operator <code>,</code></a></dt>
|
||||
|
||||
<dt><a href="#functions">Functions (deprecated)</a></dt>
|
||||
|
||||
<dd>
|
||||
<dl class="page-index">
|
||||
@@ -57,27 +84,95 @@
|
||||
|
||||
<p>A <b>keyword-expression</b> results in an object which holds a
|
||||
sequence of <a href="definitions.html#ntbs">ntbs</a>es, and whose type
|
||||
encodes the number of keywords specified.</p>
|
||||
encodes the number of keywords specified. The <b>keyword-expression</b>
|
||||
may contain default values for some or all of the keywords it holds</p>
|
||||
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
<h2><a name="classes"></a>Classes</h2>
|
||||
|
||||
<h3><a name="args-spec"></a><code>args(</code>...<code>)</code></h3>
|
||||
<h3><a name="arg-spec"></a><code>class arg;</code></h3>
|
||||
|
||||
<p>The objects of class arg are keyword-expressions holding one keyword (
|
||||
size one )</p>
|
||||
|
||||
<h4><a name="arg-synopsis"></a>Class <code>arg</code> synopsis</h4>
|
||||
<pre>
|
||||
<i>unspecified1</i> args(char const*);
|
||||
<i>unspecified2</i> args(char const*, char const*);
|
||||
.
|
||||
.
|
||||
.
|
||||
<i>unspecifiedN</i> args(char const*, char const*, ... char const*);
|
||||
namespace boost { namespace python
|
||||
{
|
||||
struct arg
|
||||
{
|
||||
template <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> Every argument must be a <a href=
|
||||
<dt><b>Requires:</b> The argument must be a <a href=
|
||||
"definitions.html#ntbs">ntbs</a>.</dt>
|
||||
|
||||
<dt><b>Returns:</b> an object representing a <a href=
|
||||
"#keyword-expression"><i>keyword-expression</i></a> encapsulating the
|
||||
arguments passed.</dt>
|
||||
<dt><b>Effects:</b> Constructs an <code>arg</code> object holding a
|
||||
keyword with name <code>name</code>.</dt>
|
||||
</dl>
|
||||
|
||||
<h4><a name="arg-operator"></a>Class <code>arg</code> operator =</h4>
|
||||
<pre>
|
||||
template <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>
|
||||
@@ -85,19 +180,20 @@
|
||||
#include <boost/python/def.hpp>
|
||||
using namespace boost::python;
|
||||
|
||||
int f(int x, int y, int z);
|
||||
int f(double x, double y, double z=0.0, double w=1.0);
|
||||
|
||||
BOOST_PYTHON_MODULE(xxx)
|
||||
{
|
||||
def("f", f, args("x", "y", "z"));
|
||||
def("f", f
|
||||
, ( arg("x"), "y", arg("z")=0.0, arg("w")=1.0 )
|
||||
);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Revised 05 November, 2001</p>
|
||||
<p>Revised 01 August, 2003</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002-2003.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<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 - Bibliography</title>
|
||||
</head>
|
||||
<body link="#0000ff" vlink="#800080">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
|
||||
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h2 align="center">Bibliography</h2>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
{{bibliographical information}}
|
||||
<hr>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
05 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,3 +1,6 @@
|
||||
<!-- 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">
|
||||
@@ -10,10 +13,10 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
|
||||
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
"C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
<h2 align="center">Header <call.hpp></h2>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -77,6 +80,6 @@ double apply2(PyObject* func, double x, double y)
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
2002. All Rights Reserved.</i></p>
|
||||
2002. </i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<!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=
|
||||
@@ -16,11 +19,11 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header <call_method.hpp></h2>
|
||||
</td>
|
||||
@@ -112,7 +115,7 @@ class Base_callback : public Base
|
||||
public:
|
||||
Base_callback(PyObject* self) : m_self(self) {}
|
||||
|
||||
char const* class_name() const { return <b>call_method</b>(m_self, "class_name"); }
|
||||
char const* class_name() const { return <b>call_method</b><char const*>(m_self, "class_name"); }
|
||||
char const* Base_name() const { return Base::class_name(); }
|
||||
private:
|
||||
PyObject* const m_self;
|
||||
@@ -147,12 +150,12 @@ BOOST_PYTHON_MODULE(my_module)
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
28 Sept, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<!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=
|
||||
@@ -16,11 +19,11 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Calling Python Functions and Methods</h2>
|
||||
</td>
|
||||
@@ -79,7 +82,7 @@ call_method<ResultType>(self_object, "<i>method-name</i>", a1, a2... a<i>N
|
||||
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#reference_wrapper">ref()</a>:</p>
|
||||
"../../../bind/ref.html">ref()</a>:</p>
|
||||
<pre>
|
||||
class X : boost::noncopyable
|
||||
{
|
||||
@@ -128,7 +131,7 @@ void apply(PyObject* callable, X& x)
|
||||
|
||||
<tr>
|
||||
<td><code><a href=
|
||||
"../../../bind/ref.html#reference_wrapper">boost::reference_wrapper</a><T></code></td>
|
||||
"../../../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
|
||||
@@ -240,12 +243,12 @@ void apply(PyObject* callable, X& x)
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
17 April, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
.. 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
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<!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=
|
||||
@@ -16,11 +19,11 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Configuration</h2>
|
||||
</td>
|
||||
@@ -47,22 +50,22 @@
|
||||
<h2><a name="app-defined"></a>Application Defined Macros</h2>
|
||||
|
||||
<p>These are the macros that may be defined by an application using
|
||||
<b>Boost.Python</b>. Note that if you extend a strict interpretation of the C++
|
||||
standard to cover dynamic libraries, using different values of these
|
||||
macros when compiling different libraries (including extension modules
|
||||
and the <b>Boost.Python</b> library itself) is a violation of the <a href=
|
||||
"definitions.html#ODR">ODR</a>. However, we know of no C++
|
||||
<b>Boost.Python</b>. Note that if you extend a strict interpretation of
|
||||
the C++ standard to cover dynamic libraries, using different values of
|
||||
these macros when compiling different libraries (including extension
|
||||
modules and the <b>Boost.Python</b> library itself) is a violation of the
|
||||
<a href="definitions.html#ODR">ODR</a>. However, we know of no C++
|
||||
implementations on which this particular violation is detectable or
|
||||
causes any problems.</p>
|
||||
|
||||
<table summary="application defined macros" width="100%" cellpadding=
|
||||
"10">
|
||||
<tr>
|
||||
<th align="left"><b>Macro</b></td>
|
||||
<th align="left"><b>Macro</b></th>
|
||||
|
||||
<th><b>Default</b></td>
|
||||
<th><b>Default</b></th>
|
||||
|
||||
<th align="left"><b>Meaning</b></td>
|
||||
<th align="left"><b>Meaning</b></th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -70,15 +73,16 @@
|
||||
|
||||
<td valign="top" align="center">15</td>
|
||||
|
||||
<td valign="top">The maximum <a href="definitions.html#arity">arity</a> of any
|
||||
function, member function, or constructor to be wrapped, invocation
|
||||
of a <b>Boost.Python</b> function wich is specified as taking arguments
|
||||
<td valign="top">The maximum <a href=
|
||||
"definitions.html#arity">arity</a> of any function, member function,
|
||||
or constructor to be wrapped, invocation of a <b>Boost.Python</b>
|
||||
function wich is specified as taking arguments
|
||||
<code>x1, 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>
|
||||
"call_method.html#call_method-spec">call_method</a><R>(</code>...
|
||||
<code>)</code>.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -86,28 +90,39 @@
|
||||
|
||||
<td valign="top" align="center">10</td>
|
||||
|
||||
<td valign="top">The maximum number of template arguments to the <code><a href=
|
||||
<td valign="top">The maximum number of template arguments to the
|
||||
<code><a href=
|
||||
"class.html#bases-spec">bases</a><</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>
|
||||
</table>
|
||||
|
||||
<h2><a name="lib-defined-impl"></a>Library Defined Implementation
|
||||
Macros</h2>
|
||||
|
||||
<p>These macros are defined by <b>Boost.Python</b> and are
|
||||
implementation details of interest only to implementors and those porting
|
||||
to new platforms.</p>
|
||||
<p>These macros are defined by <b>Boost.Python</b> and are implementation
|
||||
details of interest only to implementors and those porting to new
|
||||
platforms.</p>
|
||||
|
||||
<table summary="library defined implementation macros" width="100%"
|
||||
cellpadding="10">
|
||||
<tr>
|
||||
<th align="left"><b>Macro</b></td>
|
||||
<th align="left"><b>Macro</b></th>
|
||||
|
||||
<th><b>Default</b></td>
|
||||
<th><b>Default</b></th>
|
||||
|
||||
<th align="left"><b>Meaning</b></td>
|
||||
<th align="left"><b>Meaning</b></th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -115,27 +130,26 @@
|
||||
|
||||
<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>
|
||||
<td valign="top">If defined, this indicates that the type_info
|
||||
comparison across shared library boundaries does not work on this
|
||||
platform. In other words, if shared-lib-1 passes
|
||||
<code>typeid(T)</code> to a function in shared-lib-2 which compares
|
||||
it to <code>typeid(T)</code>, that comparison may return
|
||||
<code>false</code>. If this macro is #defined, Boost.Python uses and
|
||||
compares <code>typeid(T).name()</code> instead of using and comparing
|
||||
the <code>std::type_info</code> objects directly.</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
04 October, 2002
|
||||
7 January, 2003
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<!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=
|
||||
@@ -17,11 +20,11 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header
|
||||
<boost/python/copy_const_reference.hpp></h2>
|
||||
@@ -135,13 +138,12 @@ BOOST_PYTHON_MODULE(my_module)
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
29 September, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<!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=
|
||||
@@ -17,11 +20,11 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header
|
||||
<boost/python/copy_non_const_reference.hpp></h2>
|
||||
@@ -135,13 +138,12 @@ BOOST_PYTHON_MODULE(my_module)
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
29 September, 2001
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
<!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">
|
||||
"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">
|
||||
|
||||
@@ -16,11 +19,11 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header
|
||||
<boost/python/data_members.hpp></h2>
|
||||
@@ -77,7 +80,48 @@ template <class C, class D, class Policies>
|
||||
<code>C*</code>, and returns the corresponding member <code>D</code>
|
||||
member of the <code>C</code> object, converted <code>to_python</code>.
|
||||
If <code>policies</code> is supplied, it will be applied to the
|
||||
function as described <a href="CallPolicies.html">here</a>.</dt>
|
||||
function as described <a href="CallPolicies.html">here</a>. Otherwise,
|
||||
the library attempts to determine whether <code>D</code> is a
|
||||
user-defined class type, and if so uses <code><a href=
|
||||
"return_internal_reference.html#return_internal_reference-spec">return_internal_reference</a><></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
|
||||
@@ -108,6 +152,34 @@ template <class C, class D, class Policies>
|
||||
"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>
|
||||
|
||||
@@ -147,13 +219,11 @@ BOOST_PYTHON_MODULE_INIT(data_members_example)
|
||||
|
||||
<p>
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
29 September 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
5 August, 2003 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
127
doc/v2/def.html
@@ -1,9 +1,12 @@
|
||||
<!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">
|
||||
"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">
|
||||
|
||||
@@ -16,11 +19,11 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/def.hpp></h2>
|
||||
</td>
|
||||
@@ -75,6 +78,12 @@ void def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);
|
||||
|
||||
<dd>
|
||||
<ul>
|
||||
<li>If <code>Fn</code> is [derived from] <code><a href=
|
||||
"object.html#object-spec">object</a></code>, it will be added to
|
||||
the current scope as a single overload. To be useful,
|
||||
<code>fn</code> should be <a href=
|
||||
"http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-6">callable</a>.</li>
|
||||
|
||||
<li>
|
||||
If <code>a1</code> is the result of an <a href=
|
||||
"overloads.html#overload-dispatch-expression"><em>overload-dispatch-expression</em></a>,
|
||||
@@ -104,67 +113,52 @@ void def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);
|
||||
</dl>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Otherwise, a single function overload built around fn (which must
|
||||
not be null) is added to the <a href="scope.html">current
|
||||
scope</a>:
|
||||
|
||||
<ul>
|
||||
<li>If fn is a function or member function pointer,
|
||||
<code>a1</code>-<code>a3</code> (if supplied) may be selected
|
||||
in any order from the table below.</li>
|
||||
|
||||
<li>Otherwise, <code>Fn</code> must be [derived from] <code><a
|
||||
href="object.html#object-spec">object</a></code>, and
|
||||
<code>a1-a2</code> (if supplied) may be selcted in any order
|
||||
from the first two rows of the table below. To be useful,
|
||||
<code>fn</code> should be <a href=
|
||||
"http://www.python.org/doc/current/lib/built-in-funcs.html#l2h-6">
|
||||
callable</a>.</li>
|
||||
</ul>
|
||||
|
||||
<table border="1" summary="def() optional arguments">
|
||||
<tr>
|
||||
<th>Memnonic Name</th>
|
||||
|
||||
<th>Requirements/Type properties</th>
|
||||
|
||||
<th>Effects</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>docstring</td>
|
||||
|
||||
<td>Any <a href="definitions.html#ntbs">ntbs</a>.</td>
|
||||
|
||||
<td>Value will be bound to the <code>__doc__</code> attribute
|
||||
of the resulting method overload.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>policies</td>
|
||||
|
||||
<td>A model of <a href=
|
||||
"CallPolicies.html">CallPolicies</a></td>
|
||||
|
||||
<td>A copy will be used as the call policies of the resulting
|
||||
method overload.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>keywords</td>
|
||||
|
||||
<td>The result of a <a href=
|
||||
"args.html#keyword-expression"><em>keyword-expression</em></a>
|
||||
specifying no more arguments than the <a href=
|
||||
"definitions.html#arity">arity</a> of <code>fn</code>.</td>
|
||||
|
||||
<td>A copy will be used as the call policies of the resulting
|
||||
method overload.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</li>
|
||||
<li>Otherwise, fn must be a non-null function or member function
|
||||
pointer, and a single function overload built around fn is added to
|
||||
the <a href="scope.html">current scope</a>. If any of
|
||||
<code>a1</code>-<code>a3</code> are supplied, they may be selected
|
||||
in any order from the table below.</li>
|
||||
</ul>
|
||||
|
||||
<table border="1" summary="def() optional arguments">
|
||||
<tr>
|
||||
<th>Memnonic Name</th>
|
||||
|
||||
<th>Requirements/Type properties</th>
|
||||
|
||||
<th>Effects</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>docstring</td>
|
||||
|
||||
<td>Any <a href="definitions.html#ntbs">ntbs</a>.</td>
|
||||
|
||||
<td>Value will be bound to the <code>__doc__</code> attribute of
|
||||
the resulting method overload.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>policies</td>
|
||||
|
||||
<td>A model of <a href="CallPolicies.html">CallPolicies</a></td>
|
||||
|
||||
<td>A copy will be used as the call policies of the resulting
|
||||
method overload.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>keywords</td>
|
||||
|
||||
<td>The result of a <a href=
|
||||
"args.html#keyword-expression"><em>keyword-expression</em></a>
|
||||
specifying no more arguments than the <a href=
|
||||
"definitions.html#arity">arity</a> of <code>fn</code>.</td>
|
||||
|
||||
<td>A copy will be used as the call policies of the resulting
|
||||
method overload.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
@@ -174,6 +168,8 @@ void def(char const* name, Fn fn, A1 const&, A2 const&, A3 const&);
|
||||
#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)
|
||||
@@ -184,13 +180,12 @@ BOOST_PYTHON_MODULE(def_test)
|
||||
|
||||
<p>
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
03 October, 2002
|
||||
7 March, 2003
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
"../../../../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)
|
||||
@@ -11,10 +11,10 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
|
||||
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
"C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header
|
||||
<boost/python/default_call_policies.hpp></h2>
|
||||
@@ -161,10 +161,12 @@ struct return_value_policy : Base
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
05 November, 2001
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
|
||||
|
||||
<p><i>© Copyright <a href="../../../../people/dave_abrahams.htm">Dave
|
||||
Abrahams</a> 2002. All Rights Reserved.</i>
|
||||
<p><i>© Copyright <a href="../../../../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>
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<!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=
|
||||
@@ -16,11 +19,11 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Definitions</h2>
|
||||
</td>
|
||||
@@ -88,13 +91,12 @@
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
03 October, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
13 November, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<!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=
|
||||
@@ -16,11 +19,11 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/dict.hpp></h2>
|
||||
</td>
|
||||
@@ -143,8 +146,7 @@ dict swap_object_dict(object target, dict d)
|
||||
<p>Revised 30 September, 2002</p>
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
339
doc/v2/docstring_options.html
Normal file
@@ -0,0 +1,339 @@
|
||||
<!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();
|
||||
|
||||
void
|
||||
disable_user_defined();
|
||||
|
||||
void
|
||||
enable_user_defined();
|
||||
|
||||
void
|
||||
disable_signatures();
|
||||
|
||||
void
|
||||
enable_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 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>, 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>
|
||||
|
||||
<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_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 both 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 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");
|
||||
}
|
||||
</pre>Python code:
|
||||
<pre>
|
||||
>>> import demo
|
||||
>>> print demo.foo1.__doc__
|
||||
foo1 doc
|
||||
C++ signature:
|
||||
foo1(int i) -> int
|
||||
>>> print demo.foo2.__doc__
|
||||
C++ signature:
|
||||
foo2(long l) -> int
|
||||
>>> print demo.foo3.__doc__
|
||||
None
|
||||
>>> print demo.foo4.__doc__
|
||||
foo4 doc
|
||||
</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=
|
||||
"../../../../people/ralf_w_grosse_kunstleve.htm">Ralf W.
|
||||
Grosse-Kunstleve</a> 2006.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,5 +1,8 @@
|
||||
<!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=
|
||||
@@ -16,11 +19,11 @@
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="../../../../index.htm"><img height="86" width="277"
|
||||
alt="C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
|
||||
alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td valign="top">
|
||||
<h1 align="center">Boost.Python</h1>
|
||||
<h1 align="center"><a href="../index.html">Boost.Python</a></h1>
|
||||
|
||||
<h2 align="center">Header <boost/python/enum.hpp></h2>
|
||||
</td>
|
||||
@@ -87,7 +90,8 @@ namespace boost { namespace python
|
||||
class enum_ : public <a href="object.html#object-spec">object</a>
|
||||
{
|
||||
enum_(char const* name);
|
||||
inline enum_<T>& value(char const* name, T);
|
||||
enum_<T>& value(char const* name, T);
|
||||
enum_<T>& export_values();
|
||||
};
|
||||
}}
|
||||
</pre>
|
||||
@@ -133,6 +137,21 @@ inline enum_<T>& value(char const* name, T x);
|
||||
|
||||
</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
|
||||
@@ -152,6 +171,7 @@ BOOST_PYTHON_MODULE(enums)
|
||||
enum_<color>("color")
|
||||
.value("red", red)
|
||||
.value("green", green)
|
||||
.export_values()
|
||||
.value("blue", blue)
|
||||
;
|
||||
|
||||
@@ -162,12 +182,23 @@ BOOST_PYTHON_MODULE(enums)
|
||||
<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
|
||||
|
||||
@@ -192,12 +223,12 @@ TypeError: bad argument type for built-in operation
|
||||
|
||||
Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
||||
03 October, 2002 <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
13 December, 2002
|
||||
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
|
||||
|
||||
|
||||
<p><i>© Copyright <a href=
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All Rights
|
||||
Reserved.</i></p>
|
||||
"../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002.</i></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||