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"><</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">></span> 53<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">def</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 54<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">to_python_converter</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></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">&</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">&</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">&</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">&</span><span class="identifier">convertible</span><span class="special">,</span> 82 <span class="special">&</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"><</span><span class="identifier">custom_string</span><span class="special">>());</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"><</span><span class="identifier">custom_string</span><span class="special">>*)</span> 100 <span class="identifier">data</span><span class="special">)-></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">-></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">&</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"><</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">>();</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::<anonymous></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