Boost logo

Boost-Commit :

From: oryol_at_[hidden]
Date: 2008-02-09 23:22:33


Author: jeremypack
Date: 2008-02-09 23:22:32 EST (Sat, 09 Feb 2008)
New Revision: 43203
URL: http://svn.boost.org/trac/boost/changeset/43203

Log:
extension/reflection example

Added:
   sandbox/libs/reflection/doc/html/boost_reflection/extension.html (contents, props changed)

Added: sandbox/libs/reflection/doc/html/boost_reflection/extension.html
==============================================================================
--- (empty file)
+++ sandbox/libs/reflection/doc/html/boost_reflection/extension.html 2008-02-09 23:22:32 EST (Sat, 09 Feb 2008)
@@ -0,0 +1,228 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title> Boost.Extension Interoperability</title>
+<link rel="stylesheet" href="../boostbook.css" type="text/css">
+<meta name="generator" content="DocBook XSL Stylesheets V1.67.2">
+<link rel="start" href="../index.html" title="Chapter 1. Boost.Reflection 1.0">
+<link rel="up" href="../index.html" title="Chapter 1. Boost.Reflection 1.0">
+<link rel="prev" href="introduction.html" title=" Introduction">
+<link rel="next" href="tutorials.html" title="Tutorials">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>
+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
+<td align="center">Home</td>
+<td align="center">Libraries</td>
+<td align="center">People</td>
+<td align="center">FAQ</td>
+<td align="center">More</td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="introduction.html"><img src="../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="tutorials.html"><img src="../../../doc/html/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="boost_reflection.extension"></a> Boost.Extension Interoperability</h2></div></div></div>
+<p>
+ Reflections are designed to work with Boost.Extension, or with shared libraries
+ in general. A simple example is included in examples<span class="emphasis"><em>extension</em></span>.
+ </p>
+<p>
+ Declaring the reflected class itself is similar to the process for doing the
+ same in Boost.Extension.
+ </p>
+<p>
+ Here's how the Jamfile for these libraries is defined. Note that, like in Boost.Extension,
+ one can rename the shared library extensions, for consistency across platforms.
+ Here, we use the .reflection suffix for each shared library.
+</p>
+<pre class="programlisting">
+<span class="identifier">import</span> <span class="identifier">type</span> <span class="special">:</span> <span class="identifier">change</span><span class="special">-</span><span class="identifier">generated</span><span class="special">-</span><span class="identifier">target</span><span class="special">-</span><span class="identifier">suffix</span> <span class="special">;</span>
+<span class="identifier">import</span> <span class="identifier">type</span> <span class="special">:</span> <span class="identifier">change</span><span class="special">-</span><span class="identifier">generated</span><span class="special">-</span><span class="identifier">target</span><span class="special">-</span><span class="identifier">prefix</span> <span class="special">;</span>
+<span class="identifier">type</span><span class="special">.</span><span class="identifier">change</span><span class="special">-</span><span class="identifier">generated</span><span class="special">-</span><span class="identifier">target</span><span class="special">-</span><span class="identifier">suffix</span> <span class="identifier">SHARED_LIB</span> <span class="special">:</span> <span class="special">:</span> <span class="identifier">reflection</span> <span class="special">;</span>
+<span class="identifier">type</span><span class="special">.</span><span class="identifier">change</span><span class="special">-</span><span class="identifier">generated</span><span class="special">-</span><span class="identifier">target</span><span class="special">-</span><span class="identifier">prefix</span> <span class="identifier">SHARED_LIB</span> <span class="special">:</span> <span class="special">:</span> <span class="identifier">lib</span> <span class="special">;</span>
+<span class="identifier">exe</span> <span class="identifier">extension</span><span class="special">-</span><span class="identifier">reflection</span> <span class="special">:</span> <span class="identifier">extension</span><span class="special">/</span><span class="identifier">extension</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">;</span>
+<span class="identifier">lib</span> <span class="identifier">car_lib</span> <span class="special">:</span> <span class="identifier">extension</span><span class="special">/</span><span class="identifier">car_lib</span><span class="special">.</span><span class="identifier">cpp</span> <span class="special">:</span> <span class="special">&lt;</span><span class="identifier">link</span><span class="special">&gt;</span><span class="identifier">shared</span> <span class="special">;</span>
+</pre>
+<p>
+ </p>
+<p>
+ The code in the shared library is defined in car_lib.cpp.
+ </p>
+<p>
+ We define two classes to export as reflections. Although both of these classes
+ are derived from a common base, this is certainly not necessary. If we were
+ using Boost.Extension factories, this would be required.
+</p>
+<pre class="programlisting">
+<span class="keyword">class</span> <span class="identifier">suv</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">car</span>
+<span class="special">{</span>
+<span class="keyword">public</span><span class="special">:</span>
+ <span class="identifier">suv</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span> <span class="identifier">name</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">car</span><span class="special">(</span><span class="identifier">name</span><span class="special">)</span> <span class="special">{}</span>
+ <span class="keyword">virtual</span> <span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span> <span class="identifier">get_type</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="string">"It's an SUV."</span><span class="special">;</span> <span class="special">}</span>
+ <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">suv</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{}</span>
+<span class="special">};</span>
+
+<span class="keyword">class</span> <span class="identifier">compact</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">car</span>
+<span class="special">{</span>
+<span class="keyword">public</span><span class="special">:</span>
+ <span class="identifier">compact</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span> <span class="identifier">name</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">car</span><span class="special">(</span><span class="identifier">name</span><span class="special">)</span> <span class="special">{}</span>
+ <span class="keyword">virtual</span> <span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span> <span class="identifier">get_type</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="string">"It's a compact."</span><span class="special">;</span> <span class="special">}</span>
+ <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">compact</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{}</span>
+<span class="special">};</span>
+</pre>
+<p>
+ </p>
+<p>
+ Just like Boost.Extension, an external function needs to be defined that will
+ be called by the main module.
+ </p>
+<p>
+ extern "C" void BOOST_EXTENSION_EXPORT_DECL extension_export_car(std::map&lt;std::string,
+ reflection&gt; reflection_map) { reflection &amp; first = reflection_map&#8220;<span class="quote">suv"</span>&#8221;;
+ reflection &amp; second = reflection_map&#8220;<span class="quote">compact"</span>&#8221;;
+ </p>
+<pre class="programlisting">
+<span class="comment">// Create a reflector for each type that is being reflected.
+</span><span class="identifier">reflector</span><span class="special">&lt;</span><span class="identifier">suv</span><span class="special">&gt;</span> <span class="identifier">suv_reflector</span><span class="special">(&amp;</span><span class="identifier">first</span><span class="special">);</span>
+<span class="identifier">reflector</span><span class="special">&lt;</span><span class="identifier">compact</span><span class="special">&gt;</span> <span class="identifier">compact_reflector</span><span class="special">(&amp;</span><span class="identifier">second</span><span class="special">);</span>
+
+<span class="comment">// Reflect the constructor with a `const char*` arg
+</span><span class="identifier">suv_reflector</span><span class="special">.</span><span class="identifier">reflect_constructor</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;();</span>
+<span class="identifier">compact_reflector</span><span class="special">.</span><span class="identifier">reflect_constructor</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;();</span>
+
+<span class="comment">// Reflect a function for each
+</span><span class="identifier">suv_reflector</span><span class="special">.</span><span class="identifier">reflect</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;(&amp;</span><span class="identifier">suv</span><span class="special">::</span><span class="identifier">get_type</span><span class="special">,</span> <span class="string">"get_type"</span><span class="special">);</span>
+<span class="identifier">compact_reflector</span><span class="special">.</span><span class="identifier">reflect</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;(&amp;</span><span class="identifier">compact</span><span class="special">::</span><span class="identifier">get_type</span><span class="special">,</span> <span class="string">"get_type"</span><span class="special">);</span>
+</pre>
+<p>
+ // Create a reflector for each type that is being reflected. reflector&lt;suv&gt;
+ suv_reflector(&amp;first); reflector&lt;compact&gt; compact_reflector(&amp;second);
+ </p>
+<pre class="programlisting">
+<span class="comment">// Reflect the constructor with a `const char*` arg
+</span><span class="identifier">suv_reflector</span><span class="special">.</span><span class="identifier">reflect_constructor</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;();</span>
+<span class="identifier">compact_reflector</span><span class="special">.</span><span class="identifier">reflect_constructor</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;();</span>
+
+<span class="comment">// Reflect a function for each
+</span><span class="identifier">suv_reflector</span><span class="special">.</span><span class="identifier">reflect</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;(&amp;</span><span class="identifier">suv</span><span class="special">::</span><span class="identifier">get_type</span><span class="special">,</span> <span class="string">"get_type"</span><span class="special">);</span>
+<span class="identifier">compact_reflector</span><span class="special">.</span><span class="identifier">reflect</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;(&amp;</span><span class="identifier">compact</span><span class="special">::</span><span class="identifier">get_type</span><span class="special">,</span> <span class="string">"get_type"</span><span class="special">);</span>
+</pre>
+<p>
+ // Reflect the constructor with a <code class="computeroutput"><span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span></code> arg suv_reflector.reflect_constructor&lt;const
+ char *&gt;(); compact_reflector.reflect_constructor&lt;const char *&gt;();
+ </p>
+<pre class="programlisting">
+<span class="comment">// Reflect a function for each
+</span><span class="identifier">suv_reflector</span><span class="special">.</span><span class="identifier">reflect</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;(&amp;</span><span class="identifier">suv</span><span class="special">::</span><span class="identifier">get_type</span><span class="special">,</span> <span class="string">"get_type"</span><span class="special">);</span>
+<span class="identifier">compact_reflector</span><span class="special">.</span><span class="identifier">reflect</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;(&amp;</span><span class="identifier">compact</span><span class="special">::</span><span class="identifier">get_type</span><span class="special">,</span> <span class="string">"get_type"</span><span class="special">);</span>
+</pre>
+<p>
+ // Reflect a function for each suv_reflector.reflect&lt;const char *&gt;(&amp;suv::get_type,
+ "get_type"); compact_reflector.reflect&lt;const char *&gt;(&amp;compact::get_type,
+ "get_type"); }
+ </p>
+<p>
+ This is all that is necessary to export one constructor and one function for
+ each class.
+ </p>
+<p>
+ Now, in extension.cpp, we combine Boost.Extension and Boost.Reflection code
+ to load and use the reflections declared in the shared library.
+ </p>
+<p>
+ Create a mapping of reflections to strings that will be populated inside the
+ shared library.
+</p>
+<pre class="programlisting">
+<span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">reflection</span><span class="special">&gt;</span> <span class="identifier">reflection_map</span><span class="special">;</span>
+</pre>
+<p>
+ Load the shared library using Boost.Extension.
+</p>
+<pre class="programlisting">
+<span class="identifier">boost</span><span class="special">::</span><span class="identifier">extensions</span><span class="special">::</span><span class="identifier">shared_library</span> <span class="identifier">lib</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="identifier">BOOST_EXTENSION_DIR_START</span><span class="special">)</span> <span class="special">+</span>
+ <span class="string">"libcar_lib.extension"</span><span class="special">).</span><span class="identifier">c_str</span><span class="special">());</span>
+<span class="identifier">lib</span><span class="special">.</span><span class="identifier">open</span><span class="special">();</span>
+</pre>
+<p>
+ Call an exported function to populate reflection_map.
+</p>
+<pre class="programlisting">
+<span class="identifier">lib</span><span class="special">.</span><span class="identifier">get</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span>
+ <span class="identifier">reflection</span><span class="special">&gt;</span> <span class="special">&amp;&gt;</span>
+ <span class="special">(</span><span class="string">"extension_export_car"</span><span class="special">)(</span><span class="identifier">reflection_map</span><span class="special">);</span>
+<span class="keyword">if</span> <span class="special">(</span><span class="identifier">reflection_map</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">!=</span> <span class="identifier">size_t</span><span class="special">(</span><span class="number">2</span><span class="special">))</span> <span class="special">{</span>
+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Could not load reflections!"</span><span class="special">;</span>
+ <span class="keyword">return</span> <span class="number">1</span><span class="special">;</span>
+<span class="special">}</span>
+</pre>
+<p>
+ Pull out two reflections that were named "suv" and "compact"
+ respectively.
+</p>
+<pre class="programlisting">
+<span class="identifier">reflection</span> <span class="special">&amp;</span> <span class="identifier">first_reflection</span> <span class="special">=</span>
+ <span class="identifier">reflection_map</span><span class="special">[</span><span class="string">"suv"</span><span class="special">];</span>
+<span class="identifier">reflection</span> <span class="special">&amp;</span> <span class="identifier">second_reflection</span> <span class="special">=</span>
+ <span class="identifier">reflection_map</span><span class="special">[</span><span class="string">"compact"</span><span class="special">];</span>
+</pre>
+<p>
+ Use the get_constructor function to find a constructor that takes one argument,
+ a const char*.
+</p>
+<pre class="programlisting">
+<span class="identifier">instance_constructor</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;</span> <span class="identifier">first_constructor</span> <span class="special">=</span>
+ <span class="identifier">first_reflection</span><span class="special">.</span><span class="identifier">get_constructor</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;();</span>
+</pre>
+<p>
+ Use the constructor retrieved to create an instance. Warning! instances should
+ only be used with functions and constructors generated by a single reflection
+ object.
+</p>
+<pre class="programlisting">
+<span class="identifier">instance</span> <span class="identifier">first_instance</span> <span class="special">=</span>
+ <span class="identifier">first_constructor</span><span class="special">(</span><span class="string">"First Instance"</span><span class="special">);</span>
+</pre>
+<p>
+ Get a function to call on this instance.
+</p>
+<pre class="programlisting">
+<span class="identifier">boost</span><span class="special">::</span><span class="identifier">reflections</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;</span> <span class="identifier">first_function</span> <span class="special">=</span>
+ <span class="identifier">first_reflection</span><span class="special">.</span><span class="identifier">get_function</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;(</span><span class="string">"get_type"</span><span class="special">);</span>
+<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"First reflection: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">first_function</span><span class="special">(</span><span class="identifier">first_instance</span><span class="special">)</span>
+ <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
+ </pre>
+<p>
+ Repeat the steps for the second reflection.
+</p>
+<pre class="programlisting">
+<span class="identifier">instance_constructor</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;</span> <span class="identifier">second_constructor</span> <span class="special">=</span>
+ <span class="identifier">second_reflection</span><span class="special">.</span><span class="identifier">get_constructor</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;();</span>
+<span class="identifier">instance</span> <span class="identifier">second_instance</span> <span class="special">=</span>
+ <span class="identifier">second_constructor</span><span class="special">(</span><span class="string">"Second Instance"</span><span class="special">);</span>
+<span class="identifier">boost</span><span class="special">::</span><span class="identifier">reflections</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;</span> <span class="identifier">second_function</span> <span class="special">=</span>
+ <span class="identifier">second_reflection</span><span class="special">.</span><span class="identifier">get_function</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*&gt;(</span><span class="string">"get_type"</span><span class="special">);</span>
+<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Second reflection: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">second_function</span><span class="special">(</span><span class="identifier">second_instance</span><span class="special">)</span>
+ <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
+</pre>
+<p>
+ </p>
+</div>
+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
+<td align="left"></td>
+<td align="right"><div class="copyright-footer">Copyright © 2007 -2008 Jeremy Pack, Mariano G. Consoni<p>
+ 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>
+</div></td>
+</tr></table>
+<hr>
+<div class="spirit-nav">
+<a accesskey="p" href="introduction.html"><img src="../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="tutorials.html"><img src="../../../doc/html/images/next.png" alt="Next"></a>
+</div>
+</body>
+</html>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk