• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
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 5. 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
56<span class="keyword">namespace</span> <span class="identifier">sandbox</span> <span class="special">{</span> <span class="keyword">namespace</span> <span class="special">{</span>
57
58<span class="keyword">class</span> <span class="identifier">custom_string</span>
59<span class="special">{</span>
60  <span class="keyword">public</span><span class="special">:</span>
61    <span class="identifier">custom_string</span><span class="special">()</span> <span class="special">{}</span>
62    <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>
63    <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>
64  <span class="keyword">private</span><span class="special">:</span>
65    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">value_</span><span class="special">;</span>
66<span class="special">};</span>
67
68<span class="keyword">struct</span> <span class="identifier">custom_string_to_python_str</span>
69<span class="special">{</span>
70  <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>
71  <span class="special">{</span>
72    <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>
73  <span class="special">}</span>
74<span class="special">};</span>
75
76<span class="keyword">struct</span> <span class="identifier">custom_string_from_python_str</span>
77<span class="special">{</span>
78  <span class="identifier">custom_string_from_python_str</span><span class="special">()</span>
79  <span class="special">{</span>
80    <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>
81      <span class="special">&amp;</span><span class="identifier">convertible</span><span class="special">,</span>
82      <span class="special">&amp;</span><span class="identifier">construct</span><span class="special">,</span>
83      <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>
84  <span class="special">}</span>
85
86  <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>
87  <span class="special">{</span>
88    <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>
89    <span class="keyword">return</span> <span class="identifier">obj_ptr</span><span class="special">;</span>
90  <span class="special">}</span>
91
92  <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">construct</span><span class="special">(</span>
93    <span class="identifier">PyObject</span><span class="special">*</span> <span class="identifier">obj_ptr</span><span class="special">,</span>
94    <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>
95  <span class="special">{</span>
96    <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>
97    <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>
98    <span class="keyword">void</span><span class="special">*</span> <span class="identifier">storage</span> <span class="special">=</span> <span class="special">(</span>
99      <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>
100        <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>
101    <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>
102    <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>
103  <span class="special">}</span>
104<span class="special">};</span>
105
106<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>
107
108<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>
109
110<span class="keyword">void</span> <span class="identifier">init_module</span><span class="special">()</span>
111<span class="special">{</span>
112  <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>
113
114  <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>
115    <span class="identifier">custom_string</span><span class="special">,</span>
116    <span class="identifier">custom_string_to_python_str</span><span class="special">&gt;();</span>
117
118  <span class="identifier">custom_string_from_python_str</span><span class="special">();</span>
119
120  <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>
121  <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>
122<span class="special">}</span>
123
124<span class="special">}}</span> <span class="comment">// namespace sandbox::&lt;anonymous&gt;</span>
125
126<span class="identifier">BOOST_PYTHON_MODULE</span><span class="special">(</span><span class="identifier">custom_string</span><span class="special">)</span>
127<span class="special">{</span>
128  <span class="identifier">sandbox</span><span class="special">::</span><span class="identifier">init_module</span><span class="special">();</span>
129<span class="special">}</span>
130</pre>
131</div>
132<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
133<td align="left"></td>
134<td align="right"><div class="copyright-footer">Copyright © 2002-2015 David
135      Abrahams, Stefan Seefeld<p>
136        Distributed under the Boost Software License, Version 1.0. (See accompanying
137        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>)
138      </p>
139</div></td>
140</tr></table>
141<hr>
142<div class="spirit-nav">
143<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>
144</div>
145</body>
146</html>
147