Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/python/doc/v2/faq.html @ 45

Last change on this file since 45 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 30.3 KB
Line 
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2
3<!-- Copyright David Abrahams 2006. Distributed under the Boost -->
4<!-- Software License, Version 1.0. (See accompanying -->
5<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
6<html>
7  <head>
8    <meta name="generator" content=
9    "HTML Tidy for Cygwin (vers 1st April 2002), see www.w3.org">
10    <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
11    <link rel="stylesheet" type="text/css" href="../boost.css">
12
13    <title>Boost.Python - FAQ</title>
14  </head>
15
16  <body link="#0000ff" vlink="#800080">
17    <table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
18    "header">
19      <tr>
20        <td valign="top" width="300">
21          <h3><a href="../../../../index.htm"><img height="86" width="277"
22          alt="C++ Boost" src="../../../../boost.png" border="0"></a></h3>
23        </td>
24
25        <td valign="top">
26          <h1 align="center"><a href="../index.html">Boost.Python</a></h1>
27
28          <h2 align="center">Frequently Asked Questions (FAQs)</h2>
29        </td>
30      </tr>
31    </table>
32    <hr>
33
34    <dl class="page-index">
35
36      <dt><a href="#funcptr">How can I wrap a function which takes a
37      function pointer as an argument?</a><dd>
38
39      <dt><a href="#dangling">I'm getting the "attempt to return dangling
40      reference" error. What am I doing wrong?</a></dt>
41
42      <dt><a href="#question1">Is return_internal_reference
43      efficient?</a></dt>
44
45      <dt><a href="#question2">How can I wrap functions which take C++
46      containers as arguments?</a></dt>
47
48      <dt><a href="#c1204">fatal error C1204:Compiler limit:internal
49      structure overflow</a></dt>
50
51      <dt><a href="#debugging">How do I debug my Python extensions?</a></dt>
52
53      <dt><a href="#imul">Why doesn't my <code>*=</code> operator
54      work?</a></dt>
55
56      <dt><a href="#macosx">Does Boost.Python work with Mac OS X?</a></dt>
57
58      <dt><a href="#xref">How can I find the existing PyObject that holds a
59      C++ object?</a></dt>
60
61      <dt><a href="#ownership">How can I wrap a function which needs to take
62      ownership of a raw pointer?</a></dt>
63
64      <dt><a href="#slow_compilation">Compilation takes too much time and eats too much memory!
65      What can I do to make it faster?</a></dt>
66
67      <dt><a href="#packages">How do I create sub-packages using Boost.Python?</a></dt>
68
69      <dt><a href="#msvcthrowbug"
70      >error C2064: term does not evaluate to a function taking 2 arguments</a>
71      </dt>
72
73      <dt><a href="#custom_string"
74      >How can I automatically convert my custom string type to
75       and from a Python string?</a></dt>
76
77      <dt><a href="#topythonconversionfailed">Why is my automatic to-python conversion not being
78      found?</a></dt>
79
80      <dt><a href="#threadsupport">Is Boost.Python thread-aware/compatible with multiple interpreters?</a></dt>
81    </dl>
82    <hr>
83
84    <h2><a name="funcptr">How can I wrap a function which takes a
85      function pointer as an argument?</a></h2>
86
87    If what you're trying to do is something like this:
88<pre>
89typedef boost::function&lt;void (string s) &gt; funcptr;
90
91void foo(funcptr fp)
92{
93    fp(&quot;hello,world!&quot;);
94}
95
96BOOST_PYTHON_MODULE(test)
97{
98    def(&quot;foo&quot;,foo) ;
99}
100</pre>
101
102And then:
103
104<pre>
105&gt;&gt;&gt; def hello(s):
106...    print s
107...
108&gt;&gt;&gt; foo(hello)
109hello, world!
110</pre>
111
112    The short answer is: &quot;you can't&quot;.  This is not a
113    Boost.Python limitation so much as a limitation of C++.  The
114    problem is that a Python function is actually data, and the only
115    way of associating data with a C++ function pointer is to store it
116    in a static variable of the function.  The problem with that is
117    that you can only associate one piece of data with every C++
118    function, and we have no way of compiling a new C++ function
119    on-the-fly for every Python function you decide to pass
120    to <code>foo</code>.  In other words, this could work if the C++
121    function is always going to invoke the <em>same</em> Python
122    function, but you probably don't want that.
123
124    <p>If you have the luxury of changing the C++ code you're
125    wrapping, pass it an <code>object</code> instead and call that;
126    the overloaded function call operator will invoke the Python
127    function you pass it behind the <code>object</code>.
128
129    <p>For more perspective on the issue, see <a
130    href="http://aspn.activestate.com/ASPN/Mail/Message/1554837">this
131    posting</a>.
132
133    <hr>
134
135    <h2><a name="dangling">I'm getting the "attempt to return dangling
136    reference" error. What am I doing wrong?</a></h2>
137    That exception is protecting you from causing a nasty crash. It usually
138    happens in response to some code like this:
139<pre>
140period const&amp; get_floating_frequency() const
141{
142  return boost::python::call_method&lt;period const&amp;&gt;(
143      m_self,"get_floating_frequency");
144}
145</pre>
146    And you get:
147<pre>
148ReferenceError: Attempt to return dangling reference to object of type:
149class period
150</pre>
151
152    <p>In this case, the Python method invoked by <code>call_method</code>
153    constructs a new Python object. You're trying to return a reference to a
154    C++ object (an instance of <code>class period</code>) contained within
155    and owned by that Python object. Because the called method handed back a
156    brand new object, the only reference to it is held for the duration of
157    <code>get_floating_frequency()</code> above. When the function returns,
158    the Python object will be destroyed, destroying the instance of
159    <code>class period</code>, and leaving the returned reference dangling.
160    That's already undefined behavior, and if you try to do anything with
161    that reference you're likely to cause a crash. Boost.Python detects this
162    situation at runtime and helpfully throws an exception instead of letting
163    you do that.<br>
164     &nbsp;</p>
165    <hr>
166
167    <h2><a name="question1"></a>Is return_internal_reference efficient?</h2>
168
169    <blockquote>
170      <b>Q:</b> <i>I have an object composed of 12 doubles. A const&amp; to
171      this object is returned by a member function of another class. From the
172      viewpoint of using the returned object in Python I do not care if I get
173      a copy or a reference to the returned object. In Boost.Python Version 2
174      I have the choice of using copy_const_reference or
175      return_internal_reference. Are there considerations that would lead me
176      to prefer one over the other, such as size of generated code or memory
177      overhead?</i>
178
179      <p><b>A:</b> copy_const_reference will make an instance with storage
180      for one of your objects, size = base_size + 12 * sizeof(double).
181      return_internal_reference will make an instance with storage for a
182      pointer to one of your objects, size = base_size + sizeof(void*).
183      However, it will also create a weak reference object which goes in the
184      source object's weakreflist and a special callback object to manage the
185      lifetime of the internally-referenced object. My guess?
186      copy_const_reference is your friend here, resulting in less overall
187      memory use and less fragmentation, also probably fewer total
188      cycles.</p>
189    </blockquote>
190    <hr>
191
192    <h2><a name="question2"></a>How can I wrap functions which take C++
193    containers as arguments?</h2>
194
195    <p>Ralf W. Grosse-Kunstleve provides these notes:</p>
196
197    <ol>
198      <li>
199        Using the regular <code>class_&lt;&gt;</code> wrapper:
200<pre>
201class_&lt;std::vector&lt;double&gt; &gt;("std_vector_double")
202  .def(...)
203  ...
204  ;
205</pre>
206        This can be moved to a template so that several types (double, int,
207        long, etc.) can be wrapped with the same code. This technique is used
208        in the file
209
210        <blockquote>
211          scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h
212        </blockquote>
213        in the "scitbx" package. The file could easily be modified for
214        wrapping std::vector&lt;&gt; instantiations.
215
216        <p>This type of C++/Python binding is most suitable for containers
217        that may contain a large number of elements (&gt;10000).</p>
218      </li>
219
220      <li>
221        Using custom rvalue converters. Boost.Python "rvalue converters"
222        match function signatures such as:
223<pre>
224void foo(std::vector&lt;double&gt; const&amp; array); // pass by const-reference
225void foo(std::vector&lt;double&gt; array); // pass by value
226</pre>
227        Some custom rvalue converters are implemented in the file
228
229        <blockquote>
230          scitbx/include/scitbx/boost_python/container_conversions.h
231        </blockquote>
232        This code can be used to convert from C++ container types such as
233        std::vector&lt;&gt; or std::list&lt;&gt; to Python tuples and vice
234        versa. A few simple examples can be found in the file
235
236        <blockquote>
237          scitbx/array_family/boost_python/regression_test_module.cpp
238        </blockquote>
239        Automatic C++ container &lt;-&gt; Python tuple conversions are most
240        suitable for containers of moderate size. These converters generate
241        significantly less object code compared to alternative 1 above.
242      </li>
243    </ol>
244    A disadvantage of using alternative 2 is that operators such as
245    arithmetic +,-,*,/,% are not available. It would be useful to have custom
246    rvalue converters that convert to a "math_array" type instead of tuples.
247    This is currently not implemented but is possible within the framework of
248    Boost.Python V2 as it will be released in the next couple of weeks. [ed.:
249    this was posted on 2002/03/10]
250
251    <p>It would also be useful to also have "custom lvalue converters" such
252    as std::vector&lt;&gt; &lt;-&gt; Python list. These converters would
253    support the modification of the Python list from C++. For example:</p>
254
255    <p>C++:</p>
256<pre>
257void foo(std::vector&lt;double&gt;&amp; array)
258{
259  for(std::size_t i=0;i&lt;array.size();i++) {
260    array[i] *= 2;
261  }
262}
263</pre>
264    Python:
265<pre>
266&gt;&gt;&gt; l = [1, 2, 3]
267&gt;&gt;&gt; foo(l)
268&gt;&gt;&gt; print l
269[2, 4, 6]
270</pre>
271    Custom lvalue converters require changes to the Boost.Python core library
272    and are currently not available.
273
274    <p>P.S.:</p>
275
276    <p>The "scitbx" files referenced above are available via anonymous
277    CVS:</p>
278<pre>
279cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx login
280cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx
281</pre>
282    <hr>
283
284    <h2><a name="c1204"></a>fatal error C1204:Compiler limit:internal
285    structure overflow</h2>
286
287    <blockquote>
288      <b>Q:</b> <i>I get this error message when compiling a large source
289      file. What can I do?</i>
290
291      <p><b>A:</b> You have two choices:</p>
292
293      <ol>
294        <li>Upgrade your compiler (preferred)</li>
295
296        <li>
297          Break your source file up into multiple translation units.
298
299          <p><code><b>my_module.cpp</b></code>:</p>
300<pre>
301...
302void more_of_my_module();
303BOOST_PYTHON_MODULE(my_module)
304{
305   def("foo", foo);
306   def("bar", bar);
307   ...
308   more_of_my_module();
309}
310</pre>
311          <code><b>more_of_my_module.cpp</b></code>:
312<pre>
313void more_of_my_module()
314{
315   def("baz", baz);
316   ...
317}
318</pre>
319          If you find that a <code><a href=
320          "class.html#class_-spec">class_</a>&lt;...&gt;</code> declaration
321          can't fit in a single source file without triggering the error, you
322          can always pass a reference to the <code>class_</code> object to a
323          function in another source file, and call some of its member
324          functions (e.g. <code>.def(...)</code>) in the auxilliary source
325          file:
326
327          <p><code><b>more_of_my_class.cpp</b></code>:</p>
328<pre>
329void more_of_my_class(class&lt;my_class&gt;&amp; x)
330{
331   x
332     .def("baz", baz)
333     .add_property("xx", &amp;my_class::get_xx, &amp;my_class::set_xx)
334     ;
335
336   ...
337}
338</pre>
339        </li>
340      </ol>
341    </blockquote>
342    <hr>
343
344    <h2><a name="debugging"></a>How do I debug my Python extensions?</h2>
345
346    <p>Greg Burley gives the following answer for Unix GCC users:</p>
347
348    <blockquote>
349      Once you have created a boost python extension for your c++ library or
350      class, you may need to debug the code. Afterall this is one of the
351      reasons for wrapping the library in python. An expected side-effect or
352      benefit of using BPL is that debugging should be isolated to the c++
353      library that is under test, given that python code is minimal and
354      boost::python either works or it doesn't. (ie. While errors can occur
355      when the wrapping method is invalid, most errors are caught by the
356      compiler ;-).
357
358      <p>The basic steps required to initiate a gdb session to debug a c++
359      library via python are shown here. Note, however that you should start
360      the gdb session in the directory that contains your BPL my_ext.so
361      module.</p>
362<pre>
363(gdb) target exec python
364(gdb) run
365 &gt;&gt;&gt; from my_ext import *
366 &gt;&gt;&gt; [C-c]
367(gdb) break MyClass::MyBuggyFunction
368(gdb) cont
369 &gt;&gt;&gt; pyobj = MyClass()
370 &gt;&gt;&gt; pyobj.MyBuggyFunction()
371Breakpoint 1, MyClass::MyBuggyFunction ...
372Current language:  auto; currently c++
373(gdb) do debugging stuff
374</pre>
375    </blockquote>
376
377    <p>Greg's approach works even better using Emacs' "<code>gdb</code>"
378    command, since it will show you each line of source as you step through
379    it.</p>
380
381    <p>On <b>Windows</b>, my favorite debugging solution is the debugger that
382    comes with Microsoft Visual C++ 7. This debugger seems to work with code
383    generated by all versions of Microsoft and Metrowerks toolsets; it's rock
384    solid and "just works" without requiring any special tricks from the
385    user.</p>
386
387    <p>Raoul Gough has provided the following for gdb on Windows:</p>
388
389    <blockquote>
390
391      <p>gdb support for Windows DLLs has improved lately, so it is
392      now possible to debug Python extensions using a few
393      tricks. Firstly, you will need an up-to-date gdb with support
394      for minimal symbol extraction from a DLL. Any gdb from version 6
395      onwards, or Cygwin gdb-20030214-1 and onwards should do. A
396      suitable release will have a section in the gdb.info file under
397      Configuration &ndash; Native &ndash; Cygwin Native &ndash;
398      Non-debug DLL symbols. Refer to that info section for more
399      details of the procedures outlined here.</p>
400
401      <p>Secondly, it seems necessary to set a breakpoint in the
402      Python interpreter, rather than using ^C to break execution. A
403      good place to set this breakpoint is PyOS_Readline, which will
404      stop execution immediately before reading each interactive
405      Python command. You have to let Python start once under the
406      debugger, so that it loads its own DLL, before you can set the
407      breakpoint:</p>
408
409<p>
410<pre>
411$ gdb python
412GNU gdb 2003-09-02-cvs (cygwin-special)
413[...]
414
415(gdb) run
416Starting program: /cygdrive/c/Python22/python.exe
417Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32
418Type "help", "copyright", "credits" or "license" for more information.
419&gt;&gt;&gt; ^Z
420
421
422Program exited normally.
423(gdb) break *&amp;PyOS_Readline
424Breakpoint 1 at 0x1e04eff0
425(gdb) run
426Starting program: /cygdrive/c/Python22/python.exe
427Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32
428Type "help", "copyright", "credits" or "license" for more information.
429
430Breakpoint 1, 0x1e04eff0 in python22!PyOS_Readline ()
431   from /cygdrive/c/WINNT/system32/python22.dll
432(gdb) cont
433Continuing.
434&gt;&gt;&gt; from my_ext import *
435
436Breakpoint 1, 0x1e04eff0 in python22!PyOS_Readline ()
437   from /cygdrive/c/WINNT/system32/python22.dll
438(gdb) # my_ext now loaded (with any debugging symbols it contains)
439</pre>
440    </blockquote>
441
442    <h3>Debugging extensions through Boost.Build</h3>
443    If you are launching your extension module tests with <a href=
444    "../../../../tools/build/v1/build_system.htm">Boost.Build</a> using the
445    <code>boost-python-runtest</code> rule, you can ask it to launch your
446    debugger for you by adding "--debugger=<i>debugger</i>" to your bjam
447    command-line:
448<pre>
449bjam -sTOOLS=vc7.1 "--debugger=devenv /debugexe" test
450bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
451</pre>
452    It can also be extremely useful to add the <code>-d+2</code> option when
453    you run your test, because Boost.Build will then show you the exact
454    commands it uses to invoke it. This will invariably involve setting up
455    PYTHONPATH and other important environment variables such as
456    LD_LIBRARY_PATH which may be needed by your debugger in order to get
457    things to work right.
458    <hr>
459
460    <h2><a name="imul"></a>Why doesn't my <code>*=</code> operator work?</h2>
461
462    <blockquote>
463      <b>Q:</b> <i>I have exported my class to python, with many overloaded
464      operators. it works fine for me except the</i> <code>*=</code>
465      <i>operator. It always tells me "can't multiply sequence with non int
466      type". If I use</i> <code>p1.__imul__(p2)</code> <i>instead of</i>
467      <code>p1 *= p2</code><i>, it successfully executes my code. What's
468      wrong with me?</i>
469
470      <p><b>A:</b> There's nothing wrong with you. This is a bug in Python
471      2.2. You can see the same effect in Pure Python (you can learn a lot
472      about what's happening in Boost.Python by playing with new-style
473      classes in Pure Python).</p>
474<pre>
475&gt;&gt;&gt; class X(object):
476...     def __imul__(self, x):
477...         print 'imul'
478...
479&gt;&gt;&gt; x = X()
480&gt;&gt;&gt; x *= 1
481</pre>
482      To cure this problem, all you need to do is upgrade your Python to
483      version 2.2.1 or later.
484    </blockquote>
485    <hr>
486
487    <h2><a name="macosx"></a>Does Boost.Python work with Mac OS X?</h2>
488
489    It is known to work under 10.2.8 and 10.3 using
490    Apple's gcc 3.3 compiler:
491    <pre>gcc (GCC) 3.3 20030304 (Apple Computer, Inc. build 1493)</pre>
492    Under 10.2.8 get the August 2003 gcc update (free at
493    <a href="http://connect.apple.com/">http://connect.apple.com/</a>).
494    Under 10.3 get the Xcode Tools v1.0 (also free).
495    <p>
496    Python 2.3 is required. The Python that ships with 10.3 is
497    fine. Under 10.2.8 use these commands to install Python
498    as a framework:
499    <pre>./configure --enable-framework
500make
501make frameworkinstall</pre>
502    The last command requires root privileges because the target
503    directory is
504    <tt>/Library/Frameworks/Python.framework/Versions/2.3</tt>.
505    However, the installation does not interfere with the Python
506    version that ships with 10.2.8.
507    <p>
508    It is also crucial to increase the <tt>stacksize</tt> before
509    starting compilations, e.g.:
510    <pre>limit stacksize 8192k</pre>
511    If the <tt>stacksize</tt> is too small the build might crash with
512    internal compiler errors.
513    <p>
514    Sometimes Apple's compiler exhibits a bug by printing an error
515    like the following while compiling a
516    <tt>boost::python::class_&lt;your_type&gt;</tt>
517    template instantiation:
518    <pre>.../inheritance.hpp:44: error: cannot
519 dynamic_cast `p' (of type `struct cctbx::boost_python::&lt;unnamed&gt;::add_pair*
520   ') to type `void*' (source type is not polymorphic)</pre>
521
522    We do not know a general workaround, but if the definition of
523    <tt>your_type</tt> can be modified the following was found
524    to work in all cases encountered so far:<pre>struct your_type
525{
526  // before defining any member data
527#if defined(__MACH__) &amp;&amp; defined(__APPLE_CC__) &amp;&amp; __APPLE_CC__ == 1493
528  bool dummy_;
529#endif
530  // now your member data, e.g.
531  double x;
532  int j;
533  // etc.
534};</pre>
535
536    <hr>
537    <h2><a name="xref">How can I find the existing PyObject that holds a C++
538    object?</a></h2>
539
540    <blockquote>
541      "I am wrapping a function that always returns a pointer to an
542      already-held C++ object."
543    </blockquote>
544    One way to do that is to hijack the mechanisms used for wrapping a class
545    with virtual functions. If you make a wrapper class with an initial
546    PyObject* constructor argument and store that PyObject* as "self", you
547    can get back to it by casting down to that wrapper type in a thin wrapper
548    function. For example:
549<pre>
550class X { X(int); virtual ~X(); ... };
551X* f();  // known to return Xs that are managed by Python objects
552
553
554// wrapping code
555
556struct X_wrap : X
557{
558    X_wrap(PyObject* self, int v) : self(self), X(v) {}
559    PyObject* self;
560};
561
562handle&lt;&gt; f_wrap()
563{
564    X_wrap* xw = dynamic_cast&lt;X_wrap*&gt;(f());
565    assert(xw != 0);
566    return handle&lt;&gt;(borrowed(xw-&gt;self));
567}
568
569...
570
571def("f", f_wrap());
572class_&lt;X,X_wrap,boost::noncopyable&gt;("X", init&lt;int&gt;())
573   ...
574   ;
575</pre>
576    Of course, if X has no virtual functions you'll have to use
577    <code>static_cast</code> instead of <code>dynamic_cast</code> with no
578    runtime check that it's valid. This approach also only works if the
579    <code>X</code> object was constructed from Python, because
580    <code>X</code>s constructed from C++ are of course never
581    <code>X_wrap</code> objects.
582
583    <p>Another approach to this requires you to change your C++ code a bit;
584    if that's an option for you it might be a better way to go. work we've
585    been meaning to get to anyway. When a <code>shared_ptr&lt;X&gt;</code> is
586    converted from Python, the shared_ptr actually manages a reference to the
587    containing Python object. When a shared_ptr&lt;X&gt; is converted back to
588    Python, the library checks to see if it's one of those "Python object
589    managers" and if so just returns the original Python object. So you could
590    just write <code>object(p)</code> to get the Python object back. To
591    exploit this you'd have to be able to change the C++ code you're wrapping
592    so that it deals with shared_ptr instead of raw pointers.</p>
593
594    <p>There are other approaches too. The functions that receive the Python
595    object that you eventually want to return could be wrapped with a thin
596    wrapper that records the correspondence between the object address and
597    its containing Python object, and you could have your f_wrap function
598    look in that mapping to get the Python object out.</p>
599
600    <hr>
601
602    <h2><a name="ownership">How can I wrap a function which needs to take
603    ownership of a raw pointer?</a></h2>
604
605    <blockquote>
606      <i>Part of an API that I'm wrapping goes something like this:</i>
607<pre>
608struct A {}; struct B { void add( A* ); }
609where B::add() takes ownership of the pointer passed to it.
610</pre>
611
612      <p><i>However:</i></p>
613<pre>
614a = mod.A()
615b = mod.B()
616b.add( a )
617del a
618del b
619# python interpreter crashes
620# later due to memory corruption.
621</pre>
622
623      <p><i>Even binding the lifetime of a</i> to b via
624      with_custodian_and_ward doesn't prevent the python object a from
625      ultimately trying to delete the object it's pointing to. Is there a way
626      to accomplish a 'transfer-of-ownership' of a wrapped C++ object?</p>
627
628      <p><i>--Bruce Lowery</i></p>
629    </blockquote>
630    Yes: Make sure the C++ object is held by auto_ptr:
631<pre>
632class_&lt;A, std::auto_ptr&lt;A&gt; &gt;("A")
633    ...
634    ;
635</pre>
636    Then make a thin wrapper function which takes an auto_ptr parameter:
637<pre>
638void b_insert(B&amp; b, std::auto_ptr&lt;A&gt; a)
639{
640    b.insert(a.get());
641    a.release();
642}
643</pre>
644    Wrap that as B.add. Note that pointers returned via <code><a href=
645    "manage_new_object.html#manage_new_object-spec">manage_new_object</a></code>
646    will also be held by <code>auto_ptr</code>, so this transfer-of-ownership
647    will also work correctly.
648
649    <hr>
650    <h2><a name="slow_compilation">Compilation takes too much time and eats too
651            much memory!  What can I do to make it faster?</a></h2>
652    <p>
653    Please refer to the <a href="../tutorial/doc/html/python/techniques.html#python.reducing_compiling_time"
654    >Reducing Compiling Time</a> section in the tutorial.
655    </p>
656
657    <hr>
658    <h2><a name="packages">How do I create sub-packages using Boost.Python?</a></h2>
659    <p>
660    Please refer to the <a href="../tutorial/doc/html/python/techniques.html#python.creating_packages"
661    >Creating Packages</a> section in the tutorial.
662    </p>
663
664    <hr>
665    <h2><a name="msvcthrowbug"></a>error C2064: term does
666        not evaluate to a function taking 2 arguments</h2>
667    <font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
668    If you see Microsoft Visual C++ 7.1 (MS Visual Studio .NET 2003) issue
669    an error message like the following it is most likely due to a bug
670    in the compiler:
671    <pre>boost\boost\python\detail\invoke.hpp(76):
672error C2064: term does not evaluate to a function taking 2 arguments"</pre>
673    This message is triggered by code like the following:
674<pre>#include &lt;boost/python.hpp&gt;
675
676using namespace boost::python;
677
678class FXThread
679{
680public:
681    bool setAutoDelete(bool doso) throw();
682};
683
684void Export_FXThread()
685{
686    class_< FXThread >("FXThread")
687        .def("setAutoDelete", &amp;FXThread::setAutoDelete)
688    ;
689}
690    </pre>
691    The bug is related to the <code>throw()</code> modifier.
692    As a workaround cast off the modifier. E.g.:
693<pre>
694        .def("setAutoDelete", (bool (FXThread::*)(bool)) &amp;FXThread::setAutoDelete)</pre>
695    <p>(The bug has been reported to Microsoft.)</p>
696
697    <hr>
698    <h2><a name="custom_string"></a>How can I automatically
699    convert my custom string type to and from a Python string?</h2>
700    <font size="-1"><i>Ralf W. Grosse-Kunstleve provides these
701    notes:</i></font><p>
702    Below is a small, self-contained demo extension module that shows
703    how to do this. Here is the corresponding trivial test:
704    <pre>import custom_string
705assert custom_string.hello() == "Hello world."
706assert custom_string.size("california") == 10</pre>
707
708    If you look at the code you will find:
709
710    <ul>
711    <li>A custom <tt>to_python</tt> converter (easy):
712        <tt>custom_string_to_python_str</tt>
713
714    <li>A custom lvalue converter (needs more code):
715        <tt>custom_string_from_python_str</tt>
716    </ul>
717
718    The custom converters are registered in the global Boost.Python
719    registry near the top of the module initialization function. Once
720    flow control has passed through the registration code the automatic
721    conversions from and to Python strings will work in any module
722    imported in the same process.
723
724<pre>#include &lt;boost/python/module.hpp&gt;
725#include &lt;boost/python/def.hpp&gt;
726#include &lt;boost/python/to_python_converter.hpp&gt;
727
728namespace sandbox { namespace {
729
730  class custom_string
731  {
732    public:
733      custom_string() {}
734      custom_string(std::string const&amp; value) : value_(value) {}
735      std::string const&amp; value() const { return value_; }
736    private:
737      std::string value_;
738  };
739
740  struct custom_string_to_python_str
741  {
742    static PyObject* convert(custom_string const&amp; s)
743    {
744      return boost::python::incref(boost::python::object(s.value()).ptr());
745    }
746  };
747
748  struct custom_string_from_python_str
749  {
750    custom_string_from_python_str()
751    {
752      boost::python::converter::registry::push_back(
753        &amp;convertible,
754        &amp;construct,
755        boost::python::type_id&lt;custom_string&gt;());
756    }
757
758    static void* convertible(PyObject* obj_ptr)
759    {
760      if (!PyString_Check(obj_ptr)) return 0;
761      return obj_ptr;
762    }
763
764    static void construct(
765      PyObject* obj_ptr,
766      boost::python::converter::rvalue_from_python_stage1_data* data)
767    {
768      const char* value = PyString_AsString(obj_ptr);
769      if (value == 0) boost::python::throw_error_already_set();
770      void* storage = (
771        (boost::python::converter::rvalue_from_python_storage&lt;custom_string&gt;*)
772          data)-&gt;storage.bytes;
773      new (storage) custom_string(value);
774      data-&gt;convertible = storage;
775    }
776  };
777
778  custom_string hello() { return custom_string(&quot;Hello world.&quot;); }
779
780  std::size_t size(custom_string const&amp; s) { return s.value().size(); }
781
782  void init_module()
783  {
784    using namespace boost::python;
785
786    boost::python::to_python_converter&lt;
787      custom_string,
788      custom_string_to_python_str&gt;();
789
790    custom_string_from_python_str();
791
792    def(&quot;hello&quot;, hello);
793    def(&quot;size&quot;, size);
794  }
795
796}} // namespace sandbox::&lt;anonymous&gt;
797
798BOOST_PYTHON_MODULE(custom_string)
799{
800  sandbox::init_module();
801}</pre>
802
803    <hr>
804    <h2><a name="topythonconversionfailed"></a
805    >Why is my automatic to-python conversion not being found?</h2>
806    <font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
807    If you define custom converters similar to the ones
808    shown above the <tt>def_readonly()</tt> and <tt>def_readwrite()</tt>
809    member functions provided by <tt>boost::python::class_</tt> for
810    direct access to your member data will not work as expected.
811    This is because <tt>def_readonly("bar",&nbsp;&amp;foo::bar)</tt> is
812    equivalent to:
813
814<pre>.add_property("bar", make_getter(&amp;foo::bar, return_internal_reference()))</pre>
815
816    Similarly, <tt>def_readwrite("bar",&nbsp;&amp;foo::bar)</tt> is
817    equivalent to:
818
819<pre>.add_property("bar", make_getter(&amp;foo::bar, return_internal_reference()),
820                     make_setter(&amp;foo::bar, return_internal_reference())</pre>
821
822    In order to define return value policies compatible with the
823    custom conversions replace <tt>def_readonly()</tt> and
824    <tt>def_readwrite()</tt> by <tt>add_property()</tt>. E.g.:
825
826<pre>.add_property("bar", make_getter(&amp;foo::bar, return_value_policy&lt;return_by_value&gt;()),
827                     make_setter(&amp;foo::bar, return_value_policy&lt;return_by_value&gt;()))</pre>
828
829    <hr>
830    <h2><a name="threadsupport"></a
831    >Is Boost.Python thread-aware/compatible with multiple interpreters?</h2>
832    <font size="-1"><i>Niall Douglas provides these notes:</i></font><p>
833    The quick answer to this is: no.</p>
834    <p>
835    The longer answer is that it can be patched to be so, but it's
836    complex. You will need to add custom lock/unlock wrapping of every
837    time your code enters Boost.Python (particularly every virtual
838    function override) plus heavily modify
839    <tt>boost/python/detail/invoke.hpp</tt> with custom unlock/lock
840    wrapping of every time Boost.Python enters your code. You must
841    furthermore take care to <i>not</i> unlock/lock when Boost.Python
842    is invoking iterator changes via <tt>invoke.hpp</tt>.</p>
843    <p>
844    There is a patched <tt>invoke.hpp</tt> posted on the C++-SIG
845    mailing list archives and you can find a real implementation of all
846    the machinery necessary to fully implement this in the TnFOX
847    project at <a href="http://sourceforge.net/projects/tnfox/"> this
848    SourceForge project location</a>.</p>
849
850    <hr>
851
852    <p>Revised
853    <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
854     12 March, 2006
855    <!--webbot bot="Timestamp" endspan i-checksum="39359" -->
856    </p>
857
858    <p><i>&copy; Copyright <a href=
859    "../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002-2006.</i></p>
860  </body>
861</html>
Note: See TracBrowser for help on using the repository browser.