how_can_i_automatically_convert_.html 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>How can I automatically convert my custom string type to and from a Python string?</title>
  5. <link rel="stylesheet" href="../boostbook.css" type="text/css">
  6. <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
  7. <link rel="home" href="../index.html" title="Boost.Python">
  8. <link rel="up" href="../faq.html" title="Chapter&#160;5.&#160;Frequently Asked Questions (FAQs)">
  9. <link rel="prev" href="error_c2064_term_does_not_evalua.html" title="error C2064: term does not evaluate to a function taking 2 arguments">
  10. <link rel="next" href="why_is_my_automatic_to_python_co.html" title="Why is my automatic to-python conversion not being found?">
  11. </head>
  12. <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
  13. <table cellpadding="2" width="100%"><tr><td valign="top"><img alt="" width="" height="" src="../images/boost.png"></td></tr></table>
  14. <hr>
  15. <div class="spirit-nav">
  16. <a accesskey="p" href="error_c2064_term_does_not_evalua.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.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="why_is_my_automatic_to_python_co.html"><img src="../images/next.png" alt="Next"></a>
  17. </div>
  18. <div class="section">
  19. <div class="titlepage"><div><div><h3 class="title">
  20. <a name="faq.how_can_i_automatically_convert_"></a><a class="link" href="how_can_i_automatically_convert_.html" title="How can I automatically convert my custom string type to and from a Python string?">How can I automatically
  21. convert my custom string type to and from a Python string?</a>
  22. </h3></div></div></div>
  23. <p>
  24. <span class="emphasis"><em>Ralf W. Grosse-Kunstleve provides these notes:</em></span>
  25. </p>
  26. <p>
  27. Below is a small, self-contained demo extension module that shows how to
  28. do this. Here is the corresponding trivial test:
  29. </p>
  30. <pre class="programlisting"><span class="identifier">import</span> <span class="identifier">custom_string</span>
  31. <span class="identifier">assert</span> <span class="identifier">custom_string</span><span class="special">.</span><span class="identifier">hello</span><span class="special">()</span> <span class="special">==</span> <span class="string">"Hello world."</span>
  32. <span class="identifier">assert</span> <span class="identifier">custom_string</span><span class="special">.</span><span class="identifier">size</span><span class="special">(</span><span class="string">"california"</span><span class="special">)</span> <span class="special">==</span> <span class="number">10</span>
  33. </pre>
  34. <p>
  35. If you look at the code you will find:
  36. </p>
  37. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
  38. <li class="listitem">
  39. A custom <code class="computeroutput"><span class="identifier">to_python</span></code> converter
  40. (easy): <code class="computeroutput"><span class="identifier">custom_string_to_python_str</span></code>
  41. </li>
  42. <li class="listitem">
  43. A custom lvalue converter (needs more code): <code class="computeroutput"><span class="identifier">custom_string_from_python_str</span></code>
  44. </li>
  45. </ul></div>
  46. <p>
  47. The custom converters are registered in the global Boost.Python registry
  48. near the top of the module initialization function. Once flow control has
  49. passed through the registration code the automatic conversions from and to
  50. Python strings will work in any module imported in the same process.
  51. </p>
  52. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">/</span><span class="identifier">module</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  53. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">/</span><span class="identifier">def</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  54. <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">python</span><span class="special">/</span><span class="identifier">to_python_converter</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
  55. <span class="keyword">namespace</span> <span class="identifier">sandbox</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="special">{</span>
  56. <span class="keyword">class</span> <span class="identifier">custom_string</span>
  57. <span class="special">{</span>
  58. <span class="keyword">public</span><span class="special">:</span>
  59. <span class="identifier">custom_string</span><span class="special">()</span> <span class="special">{}</span>
  60. <span class="identifier">custom_string</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="special">&amp;</span><span class="identifier">value</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">value_</span><span class="special">(</span><span class="identifier">value</span><span class="special">)</span> <span class="special">{}</span>
  61. <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">value</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">value_</span><span class="special">;</span> <span class="special">}</span>
  62. <span class="keyword">private</span><span class="special">:</span>
  63. <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">value_</span><span class="special">;</span>
  64. <span class="special">};</span>
  65. <span class="keyword">struct</span> <span class="identifier">custom_string_to_python_str</span>
  66. <span class="special">{</span>
  67. <span class="keyword">static</span> <span class="identifier">PyObject</span><span class="special">*</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">custom_string</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">s</span><span class="special">)</span>
  68. <span class="special">{</span>
  69. <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">incref</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">object</span><span class="special">(</span><span class="identifier">s</span><span class="special">.</span><span class="identifier">value</span><span class="special">()).</span><span class="identifier">ptr</span><span class="special">());</span>
  70. <span class="special">}</span>
  71. <span class="special">};</span>
  72. <span class="keyword">struct</span> <span class="identifier">custom_string_from_python_str</span>
  73. <span class="special">{</span>
  74. <span class="identifier">custom_string_from_python_str</span><span class="special">()</span>
  75. <span class="special">{</span>
  76. <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">converter</span><span class="special">::</span><span class="identifier">registry</span><span class="special">::</span><span class="identifier">push_back</span><span class="special">(</span>
  77. <span class="special">&amp;</span><span class="identifier">convertible</span><span class="special">,</span>
  78. <span class="special">&amp;</span><span class="identifier">construct</span><span class="special">,</span>
  79. <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">type_id</span><span class="special">&lt;</span><span class="identifier">custom_string</span><span class="special">&gt;());</span>
  80. <span class="special">}</span>
  81. <span class="keyword">static</span> <span class="keyword">void</span><span class="special">*</span> <span class="identifier">convertible</span><span class="special">(</span><span class="identifier">PyObject</span><span class="special">*</span> <span class="identifier">obj_ptr</span><span class="special">)</span>
  82. <span class="special">{</span>
  83. <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">PyString_Check</span><span class="special">(</span><span class="identifier">obj_ptr</span><span class="special">))</span> <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
  84. <span class="keyword">return</span> <span class="identifier">obj_ptr</span><span class="special">;</span>
  85. <span class="special">}</span>
  86. <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">construct</span><span class="special">(</span>
  87. <span class="identifier">PyObject</span><span class="special">*</span> <span class="identifier">obj_ptr</span><span class="special">,</span>
  88. <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">converter</span><span class="special">::</span><span class="identifier">rvalue_from_python_stage1_data</span><span class="special">*</span> <span class="identifier">data</span><span class="special">)</span>
  89. <span class="special">{</span>
  90. <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">PyString_AsString</span><span class="special">(</span><span class="identifier">obj_ptr</span><span class="special">);</span>
  91. <span class="keyword">if</span> <span class="special">(</span><span class="identifier">value</span> <span class="special">==</span> <span class="number">0</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">throw_error_already_set</span><span class="special">();</span>
  92. <span class="keyword">void</span><span class="special">*</span> <span class="identifier">storage</span> <span class="special">=</span> <span class="special">(</span>
  93. <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">converter</span><span class="special">::</span><span class="identifier">rvalue_from_python_storage</span><span class="special">&lt;</span><span class="identifier">custom_string</span><span class="special">&gt;*)</span>
  94. <span class="identifier">data</span><span class="special">)-&gt;</span><span class="identifier">storage</span><span class="special">.</span><span class="identifier">bytes</span><span class="special">;</span>
  95. <span class="keyword">new</span> <span class="special">(</span><span class="identifier">storage</span><span class="special">)</span> <span class="identifier">custom_string</span><span class="special">(</span><span class="identifier">value</span><span class="special">);</span>
  96. <span class="identifier">data</span><span class="special">-&gt;</span><span class="identifier">convertible</span> <span class="special">=</span> <span class="identifier">storage</span><span class="special">;</span>
  97. <span class="special">}</span>
  98. <span class="special">};</span>
  99. <span class="identifier">custom_string</span> <span class="identifier">hello</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">custom_string</span><span class="special">(</span><span class="string">"Hello world."</span><span class="special">);</span> <span class="special">}</span>
  100. <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">(</span><span class="identifier">custom_string</span> <span class="keyword">const</span> <span class="special">&amp;</span><span class="identifier">s</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">s</span><span class="special">.</span><span class="identifier">value</span><span class="special">().</span><span class="identifier">size</span><span class="special">();</span> <span class="special">}</span>
  101. <span class="keyword">void</span> <span class="identifier">init_module</span><span class="special">()</span>
  102. <span class="special">{</span>
  103. <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>
  104. <span class="identifier">boost</span><span class="special">::</span><span class="identifier">python</span><span class="special">::</span><span class="identifier">to_python_converter</span><span class="special">&lt;</span>
  105. <span class="identifier">custom_string</span><span class="special">,</span>
  106. <span class="identifier">custom_string_to_python_str</span><span class="special">&gt;();</span>
  107. <span class="identifier">custom_string_from_python_str</span><span class="special">();</span>
  108. <span class="identifier">def</span><span class="special">(</span><span class="string">"hello"</span><span class="special">,</span> <span class="identifier">hello</span><span class="special">);</span>
  109. <span class="identifier">def</span><span class="special">(</span><span class="string">"size"</span><span class="special">,</span> <span class="identifier">size</span><span class="special">);</span>
  110. <span class="special">}</span>
  111. <span class="special">}}</span> <span class="comment">// namespace sandbox::&lt;anonymous&gt;</span>
  112. <span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">custom_string</span><span class="special">)</span>
  113. <span class="special">{</span>
  114. <span class="identifier">sandbox</span><span class="special">::</span><span class="identifier">init_module</span><span class="special">();</span>
  115. <span class="special">}</span>
  116. </pre>
  117. </div>
  118. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  119. <td align="left"></td>
  120. <td align="right"><div class="copyright-footer">Copyright &#169; 2002-2015 David
  121. Abrahams, Stefan Seefeld<p>
  122. Distributed under the Boost Software License, Version 1.0. (See accompanying
  123. 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>)
  124. </p>
  125. </div></td>
  126. </tr></table>
  127. <hr>
  128. <div class="spirit-nav">
  129. <a accesskey="p" href="error_c2064_term_does_not_evalua.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../faq.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="why_is_my_automatic_to_python_co.html"><img src="../images/next.png" alt="Next"></a>
  130. </div>
  131. </body>
  132. </html>