1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 2<html> 3<head> 4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 5<title>Tutorial</title> 6<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css"> 7<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 8<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset"> 9<link rel="up" href="../boost_dll.html" title="Chapter 14. Boost.DLL"> 10<link rel="prev" href="getting_started.html" title="Getting started"> 11<link rel="next" href="mangled_import.html" title="Mangled Import"> 12</head> 13<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 14<table cellpadding="2" width="100%"><tr> 15<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td> 16<td align="center"><a href="../../../index.html">Home</a></td> 17<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> 18<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> 19<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> 20<td align="center"><a href="../../../more/index.htm">More</a></td> 21</tr></table> 22<hr> 23<div class="spirit-nav"> 24<a accesskey="p" href="getting_started.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_dll.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="mangled_import.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> 25</div> 26<div class="section"> 27<div class="titlepage"><div><div><h2 class="title" style="clear: both"> 28<a name="boost_dll.tutorial"></a><a class="link" href="tutorial.html" title="Tutorial">Tutorial</a> 29</h2></div></div></div> 30<div class="toc"><dl class="toc"> 31<dt><span class="section"><a href="tutorial.html#boost_dll.tutorial.plugin_basics">Plugin basics</a></span></dt> 32<dt><span class="section"><a href="tutorial.html#boost_dll.tutorial.factory_method_in_plugin">Factory 33 method in plugin</a></span></dt> 34<dt><span class="section"><a href="tutorial.html#boost_dll.tutorial.searching_for_a_symbol_in_multiple_plugins">Searching 35 for a symbol in multiple plugins</a></span></dt> 36<dt><span class="section"><a href="tutorial.html#boost_dll.tutorial.linking_plugin_into_the_executable">Linking 37 plugin into the executable</a></span></dt> 38<dt><span class="section"><a href="tutorial.html#boost_dll.tutorial.symbol_shadowing_problem__linux_">Symbol 39 shadowing problem (Linux)</a></span></dt> 40<dt><span class="section"><a href="tutorial.html#boost_dll.tutorial.executing_callbacks_on_library_unload">Executing 41 callbacks on library unload</a></span></dt> 42<dt><span class="section"><a href="tutorial.html#boost_dll.tutorial.querying_libraries_for_symbols">Querying 43 libraries for symbols</a></span></dt> 44<dt><span class="section"><a href="tutorial.html#boost_dll.tutorial.advanced_library_reference_counting">Advanced 45 library reference counting</a></span></dt> 46<dt><span class="section"><a href="tutorial.html#boost_dll.tutorial.importing_a_c_function_from_windows_dll">Importing 47 a C function from Windows dll</a></span></dt> 48</dl></div> 49<p> 50 This Tutorial is provided to give you an idea of how to create and use plugins. 51 </p> 52<div class="section"> 53<div class="titlepage"><div><div><h3 class="title"> 54<a name="boost_dll.tutorial.plugin_basics"></a><a class="link" href="tutorial.html#boost_dll.tutorial.plugin_basics" title="Plugin basics">Plugin basics</a> 55</h3></div></div></div> 56<p> 57 The first thing to do when creating your own plugins is define the plugin 58 interface. There is an example of an abstract class that will be our plugin 59 API: 60 </p> 61<p> 62</p> 63<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">config</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 64<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">string</span><span class="special">></span> 65 66<span class="keyword">class</span> <span class="identifier">BOOST_SYMBOL_VISIBLE</span> <span class="identifier">my_plugin_api</span> <span class="special">{</span> 67<span class="keyword">public</span><span class="special">:</span> 68 <span class="keyword">virtual</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> 69 <span class="keyword">virtual</span> <span class="keyword">float</span> <span class="identifier">calculate</span><span class="special">(</span><span class="keyword">float</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">float</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> 70 71 <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">my_plugin_api</span><span class="special">()</span> <span class="special">{}</span> 72<span class="special">};</span> 73</pre> 74<p> 75 </p> 76<p> 77 Now let's make a DLL/DSO library that will holds implementation of plugin 78 interface and exports it using the <code class="computeroutput"><span class="keyword">extern</span> 79 <span class="string">"C"</span></code> and <code class="computeroutput">BOOST_SYMBOL_EXPORT</code>: 80 </p> 81<p> 82</p> 83<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">config</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for BOOST_SYMBOL_EXPORT</span> 84<span class="preprocessor">#include</span> <span class="string">"../tutorial_common/my_plugin_api.hpp"</span> 85 86<span class="keyword">namespace</span> <span class="identifier">my_namespace</span> <span class="special">{</span> 87 88<span class="keyword">class</span> <span class="identifier">my_plugin_sum</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">my_plugin_api</span> <span class="special">{</span> 89<span class="keyword">public</span><span class="special">:</span> 90 <span class="identifier">my_plugin_sum</span><span class="special">()</span> <span class="special">{</span> 91 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Constructing my_plugin_sum"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 92 <span class="special">}</span> 93 94 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> 95 <span class="keyword">return</span> <span class="string">"sum"</span><span class="special">;</span> 96 <span class="special">}</span> 97 98 <span class="keyword">float</span> <span class="identifier">calculate</span><span class="special">(</span><span class="keyword">float</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">float</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> 99 <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">;</span> 100 <span class="special">}</span> 101 102 <span class="special">~</span><span class="identifier">my_plugin_sum</span><span class="special">()</span> <span class="special">{</span> 103 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Destructing my_plugin_sum ;o)"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 104 <span class="special">}</span> 105<span class="special">};</span> 106 107<span class="comment">// Exporting `my_namespace::plugin` variable with alias name `plugin`</span> 108<span class="comment">// (Has the same effect as `BOOST_DLL_ALIAS(my_namespace::plugin, plugin)`)</span> 109<span class="keyword">extern</span> <span class="string">"C"</span> <span class="identifier">BOOST_SYMBOL_EXPORT</span> <span class="identifier">my_plugin_sum</span> <span class="identifier">plugin</span><span class="special">;</span> 110<span class="identifier">my_plugin_sum</span> <span class="identifier">plugin</span><span class="special">;</span> 111 112<span class="special">}</span> <span class="comment">// namespace my_namespace</span> 113</pre> 114<p> 115 </p> 116<p> 117 Simple application that loads plugin using the <code class="computeroutput"><a class="link" href="../boost/dll/import.html" title="Function import">boost::dll::import</a></code> 118 and <code class="computeroutput"><a class="link" href="../boost/dll/load_mode/type.html" title="Type type">append_decorations</a></code>: 119 </p> 120<p> 121</p> 122<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">import</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for import_alias</span> 123<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 124<span class="preprocessor">#include</span> <span class="string">"../tutorial_common/my_plugin_api.hpp"</span> 125 126<span class="keyword">namespace</span> <span class="identifier">dll</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">;</span> 127 128<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">argc</span><span class="special">,</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">argv</span><span class="special">[])</span> <span class="special">{</span> 129 130 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">fs</span><span class="special">::</span><span class="identifier">path</span> <span class="identifier">lib_path</span><span class="special">(</span><span class="identifier">argv</span><span class="special">[</span><span class="number">1</span><span class="special">]);</span> <span class="comment">// argv[1] contains path to directory with our plugin library</span> 131 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_plugin_api</span><span class="special">></span> <span class="identifier">plugin</span><span class="special">;</span> <span class="comment">// variable to hold a pointer to plugin variable</span> 132 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Loading the plugin"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 133 134 <span class="identifier">plugin</span> <span class="special">=</span> <span class="identifier">dll</span><span class="special">::</span><span class="identifier">import</span><span class="special"><</span><span class="identifier">my_plugin_api</span><span class="special">>(</span> <span class="comment">// type of imported symbol is located between `<` and `>`</span> 135 <span class="identifier">lib_path</span> <span class="special">/</span> <span class="string">"my_plugin_sum"</span><span class="special">,</span> <span class="comment">// path to the library and library name</span> 136 <span class="string">"plugin"</span><span class="special">,</span> <span class="comment">// name of the symbol to import</span> 137 <span class="identifier">dll</span><span class="special">::</span><span class="identifier">load_mode</span><span class="special">::</span><span class="identifier">append_decorations</span> <span class="comment">// makes `libmy_plugin_sum.so` or `my_plugin_sum.dll` from `my_plugin_sum`</span> 138 <span class="special">);</span> 139 140 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"plugin->calculate(1.5, 1.5) call: "</span> <span class="special"><<</span> <span class="identifier">plugin</span><span class="special">-></span><span class="identifier">calculate</span><span class="special">(</span><span class="number">1.5</span><span class="special">,</span> <span class="number">1.5</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 141<span class="special">}</span> 142</pre> 143<p> 144 </p> 145<p> 146 That application will output: 147 </p> 148<pre class="programlisting">Loading the plugin 149Constructing my_plugin_sum 150plugin->calculate(1.5, 1.5) call: 3 151Destructing my_plugin_sum ;o) 152</pre> 153<p> 154 <span class="bold"><strong>Full sources:</strong></span> 155 </p> 156<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 157<li class="listitem"> 158 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial_common/my_plugin_api.hpp" target="_top">example/tutorial_common/my_plugin_api.hpp</a> 159 </li> 160<li class="listitem"> 161 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial1/my_plugin_sum.cpp" target="_top">example/tutorial1/my_plugin_sum.cpp</a> 162 </li> 163<li class="listitem"> 164 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial1/tutorial1.cpp" target="_top">example/tutorial1/tutorial1.cpp</a> 165 </li> 166</ul></div> 167<p> 168 <a class="link" href="tutorial.html" title="Tutorial">Back to the Top</a> 169 </p> 170</div> 171<div class="section"> 172<div class="titlepage"><div><div><h3 class="title"> 173<a name="boost_dll.tutorial.factory_method_in_plugin"></a><a class="link" href="tutorial.html#boost_dll.tutorial.factory_method_in_plugin" title="Factory method in plugin">Factory 174 method in plugin</a> 175</h3></div></div></div> 176<p> 177 In previous example we were importing from a plugin a single variable. Let's 178 make a class that uses our plugin API plugin and holds some state: 179 </p> 180<p> 181</p> 182<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">alias</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for BOOST_DLL_ALIAS </span> 183<span class="preprocessor">#include</span> <span class="string">"../tutorial_common/my_plugin_api.hpp"</span> 184 185<span class="keyword">namespace</span> <span class="identifier">my_namespace</span> <span class="special">{</span> 186 187<span class="keyword">class</span> <span class="identifier">my_plugin_aggregator</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">my_plugin_api</span> <span class="special">{</span> 188 <span class="keyword">float</span> <span class="identifier">aggr_</span><span class="special">;</span> 189 <span class="identifier">my_plugin_aggregator</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">aggr_</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">{}</span> 190 191<span class="keyword">public</span><span class="special">:</span> 192 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> 193 <span class="keyword">return</span> <span class="string">"aggregator"</span><span class="special">;</span> 194 <span class="special">}</span> 195 196 <span class="keyword">float</span> <span class="identifier">calculate</span><span class="special">(</span><span class="keyword">float</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">float</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> 197 <span class="identifier">aggr_</span> <span class="special">+=</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">;</span> 198 <span class="keyword">return</span> <span class="identifier">aggr_</span><span class="special">;</span> 199 <span class="special">}</span> 200 201 <span class="comment">// Factory method</span> 202 <span class="keyword">static</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_plugin_aggregator</span><span class="special">></span> <span class="identifier">create</span><span class="special">()</span> <span class="special">{</span> 203 <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_plugin_aggregator</span><span class="special">>(</span> 204 <span class="keyword">new</span> <span class="identifier">my_plugin_aggregator</span><span class="special">()</span> 205 <span class="special">);</span> 206 <span class="special">}</span> 207<span class="special">};</span> 208 209 210<span class="identifier">BOOST_DLL_ALIAS</span><span class="special">(</span> 211 <span class="identifier">my_namespace</span><span class="special">::</span><span class="identifier">my_plugin_aggregator</span><span class="special">::</span><span class="identifier">create</span><span class="special">,</span> <span class="comment">// <-- this function is exported with...</span> 212 <span class="identifier">create_plugin</span> <span class="comment">// <-- ...this alias name</span> 213<span class="special">)</span> 214 215<span class="special">}</span> <span class="comment">// namespace my_namespace</span> 216</pre> 217<p> 218 </p> 219<p> 220 As you may see, <code class="computeroutput"><span class="identifier">my_namespace</span><span class="special">::</span><span class="identifier">create_plugin</span></code> 221 is a factory method, that creates instances of <code class="computeroutput"><span class="identifier">my_namespace</span><span class="special">::</span><span class="identifier">my_plugin_aggregator</span></code>. 222 We export that method with the name "create_plugin" using <code class="computeroutput"><a class="link" href="../BOOST_DLL_ALIAS.html" title="Macro BOOST_DLL_ALIAS">BOOST_DLL_ALIAS</a></code>. 223 </p> 224<p> 225</p> 226<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">import</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for import_alias</span> 227<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 228<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 229<span class="preprocessor">#include</span> <span class="string">"../tutorial_common/my_plugin_api.hpp"</span> 230 231<span class="keyword">namespace</span> <span class="identifier">dll</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">;</span> 232 233<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">argc</span><span class="special">,</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">argv</span><span class="special">[])</span> <span class="special">{</span> 234 235 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">fs</span><span class="special">::</span><span class="identifier">path</span> <span class="identifier">shared_library_path</span><span class="special">(</span><span class="identifier">argv</span><span class="special">[</span><span class="number">1</span><span class="special">]);</span> <span class="comment">// argv[1] contains path to directory with our plugin library</span> 236 <span class="identifier">shared_library_path</span> <span class="special">/=</span> <span class="string">"my_plugin_aggregator"</span><span class="special">;</span> 237 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_plugin_api</span><span class="special">></span> <span class="special">(</span><span class="identifier">pluginapi_create_t</span><span class="special">)();</span> 238 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="identifier">pluginapi_create_t</span><span class="special">></span> <span class="identifier">creator</span><span class="special">;</span> 239 240 <span class="identifier">creator</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">import_alias</span><span class="special"><</span><span class="identifier">pluginapi_create_t</span><span class="special">>(</span> <span class="comment">// type of imported symbol must be explicitly specified</span> 241 <span class="identifier">shared_library_path</span><span class="special">,</span> <span class="comment">// path to library</span> 242 <span class="string">"create_plugin"</span><span class="special">,</span> <span class="comment">// symbol to import</span> 243 <span class="identifier">dll</span><span class="special">::</span><span class="identifier">load_mode</span><span class="special">::</span><span class="identifier">append_decorations</span> <span class="comment">// do append extensions and prefixes</span> 244 <span class="special">);</span> 245 246 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_plugin_api</span><span class="special">></span> <span class="identifier">plugin</span> <span class="special">=</span> <span class="identifier">creator</span><span class="special">();</span> 247 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"plugin->calculate(1.5, 1.5) call: "</span> <span class="special"><<</span> <span class="identifier">plugin</span><span class="special">-></span><span class="identifier">calculate</span><span class="special">(</span><span class="number">1.5</span><span class="special">,</span> <span class="number">1.5</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 248 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"plugin->calculate(1.5, 1.5) second call: "</span> <span class="special"><<</span> <span class="identifier">plugin</span><span class="special">-></span><span class="identifier">calculate</span><span class="special">(</span><span class="number">1.5</span><span class="special">,</span> <span class="number">1.5</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 249 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Plugin Name: "</span> <span class="special"><<</span> <span class="identifier">plugin</span><span class="special">-></span><span class="identifier">name</span><span class="special">()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 250<span class="special">}</span> 251</pre> 252<p> 253 </p> 254<p> 255 In that application we have imported the factory method using <code class="computeroutput"><a class="link" href="../boost/dll/import_alias.html" title="Function import_alias">boost::dll::import_alias</a></code>. 256 </p> 257<div class="caution"><table border="0" summary="Caution"> 258<tr> 259<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../../../doc/src/images/caution.png"></td> 260<th align="left">Caution</th> 261</tr> 262<tr><td align="left" valign="top"><p> 263 Be careful: <code class="computeroutput"><span class="identifier">creator</span></code> variable 264 holds a reference to the loaded shared library. If this variable goes out 265 of scope or will be reset, then the <span class="bold"><strong>DLL/DSO will 266 be unloaded</strong></span> and any attempt to dereference the <code class="computeroutput"><span class="identifier">plugin</span></code> variable will lead to <span class="bold"><strong>undefined behavior</strong></span>. 267 </p></td></tr> 268</table></div> 269<p> 270 Output of the application will be the following: 271 </p> 272<pre class="programlisting">plugin->calculate(1.5, 1.5) call: 3 273plugin->calculate(1.5, 1.5) second call: 6 274Plugin Name: aggregator 275</pre> 276<p> 277 <span class="bold"><strong>Full sources:</strong></span> 278 </p> 279<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 280<li class="listitem"> 281 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial2/my_plugin_aggregator.cpp" target="_top">example/tutorial2/my_plugin_aggregator.cpp</a> 282 </li> 283<li class="listitem"> 284 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial2/tutorial2.cpp" target="_top">example/tutorial2/tutorial2.cpp</a> 285 </li> 286</ul></div> 287<p> 288 <a class="link" href="tutorial.html" title="Tutorial">Back to the Top</a> 289 </p> 290</div> 291<div class="section"> 292<div class="titlepage"><div><div><h3 class="title"> 293<a name="boost_dll.tutorial.searching_for_a_symbol_in_multiple_plugins"></a><a class="link" href="tutorial.html#boost_dll.tutorial.searching_for_a_symbol_in_multiple_plugins" title="Searching for a symbol in multiple plugins">Searching 294 for a symbol in multiple plugins</a> 295</h3></div></div></div> 296<p> 297 Consider the situation: we have multiple plugins, but only some of them have 298 symbols that we need. Let's write a function that search list of plugins 299 and attempts to find <code class="computeroutput"><span class="string">"create_plugin"</span></code> 300 method. 301 </p> 302<p> 303</p> 304<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">import</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for import_alias</span> 305<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">make_shared</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 306<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 307<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 308<span class="preprocessor">#include</span> <span class="string">"../tutorial_common/my_plugin_api.hpp"</span> 309 310<span class="keyword">namespace</span> <span class="identifier">dll</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">;</span> 311 312<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">search_for_symbols</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">fs</span><span class="special">::</span><span class="identifier">path</span><span class="special">>&</span> <span class="identifier">plugins</span><span class="special">)</span> <span class="special">{</span> 313 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">plugins_found</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> 314 315 <span class="keyword">for</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="identifier">plugins</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> 316 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Loading plugin: "</span> <span class="special"><<</span> <span class="identifier">plugins</span><span class="special">[</span><span class="identifier">i</span><span class="special">]</span> <span class="special"><<</span> <span class="char">'\n'</span><span class="special">;</span> 317 <span class="identifier">dll</span><span class="special">::</span><span class="identifier">shared_library</span> <span class="identifier">lib</span><span class="special">(</span><span class="identifier">plugins</span><span class="special">[</span><span class="identifier">i</span><span class="special">],</span> <span class="identifier">dll</span><span class="special">::</span><span class="identifier">load_mode</span><span class="special">::</span><span class="identifier">append_decorations</span><span class="special">);</span> 318 <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">lib</span><span class="special">.</span><span class="identifier">has</span><span class="special">(</span><span class="string">"create_plugin"</span><span class="special">))</span> <span class="special">{</span> 319 <span class="comment">// no such symbol</span> 320 <span class="keyword">continue</span><span class="special">;</span> 321 <span class="special">}</span> 322 323 <span class="comment">// library has symbol, importing...</span> 324 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_plugin_api</span><span class="special">></span> <span class="special">(</span><span class="identifier">pluginapi_create_t</span><span class="special">)();</span> 325 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="identifier">pluginapi_create_t</span><span class="special">></span> <span class="identifier">creator</span> 326 <span class="special">=</span> <span class="identifier">dll</span><span class="special">::</span><span class="identifier">import_alias</span><span class="special"><</span><span class="identifier">pluginapi_create_t</span><span class="special">>(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">lib</span><span class="special">),</span> <span class="string">"create_plugin"</span><span class="special">);</span> 327 328 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Matching plugin name: "</span> <span class="special"><<</span> <span class="identifier">creator</span><span class="special">()-></span><span class="identifier">name</span><span class="special">()</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 329 <span class="special">++</span> <span class="identifier">plugins_found</span><span class="special">;</span> 330 <span class="special">}</span> 331 332 <span class="keyword">return</span> <span class="identifier">plugins_found</span><span class="special">;</span> 333<span class="special">}</span> 334</pre> 335<p> 336 </p> 337<p> 338 If we call that method for all our plugins we'll get the following output: 339 </p> 340<pre class="programlisting">Loading plugin: "/test/libmy_plugin_aggregator.so" 341Matching plugin name: aggregator 342Loading plugin: "/test/libmy_plugin_sum.so" 343Constructing my_plugin_sum 344Destructing my_plugin_sum ;o) 345</pre> 346<p> 347 <span class="bold"><strong>Full sources:</strong></span> 348 </p> 349<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 350<li class="listitem"> 351 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial3/tutorial3.cpp" target="_top">example/tutorial3/tutorial3.cpp</a> 352 </li> 353<li class="listitem"> 354 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial2/my_plugin_aggregator.cpp" target="_top">example/tutorial2/my_plugin_aggregator.cpp</a> 355 </li> 356<li class="listitem"> 357 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial1/my_plugin_sum.cpp" target="_top">example/tutorial1/my_plugin_sum.cpp</a> 358 </li> 359</ul></div> 360<p> 361 <a class="link" href="tutorial.html" title="Tutorial">Back to the Top</a> 362 </p> 363</div> 364<div class="section"> 365<div class="titlepage"><div><div><h3 class="title"> 366<a name="boost_dll.tutorial.linking_plugin_into_the_executable"></a><a class="link" href="tutorial.html#boost_dll.tutorial.linking_plugin_into_the_executable" title="Linking plugin into the executable">Linking 367 plugin into the executable</a> 368</h3></div></div></div> 369<p> 370 Linking plugin into the executable has the advantages of 371 </p> 372<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 373<li class="listitem"> 374 reducing common size of distribution 375 </li> 376<li class="listitem"> 377 simplification of installation of distribution 378 </li> 379<li class="listitem"> 380 faster plugin load 381 </li> 382</ul></div> 383<p> 384 Let's start from creating a linkable in plugin. Such plugin will have a header, 385 common for plugin library itself and for the executable: 386 </p> 387<p> 388</p> 389<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">alias</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for BOOST_DLL_ALIAS</span> 390<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">shared_ptr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 391<span class="preprocessor">#include</span> <span class="string">"../tutorial_common/my_plugin_api.hpp"</span> 392 393<span class="keyword">namespace</span> <span class="identifier">my_namespace</span> <span class="special">{</span> 394 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_plugin_api</span><span class="special">></span> <span class="identifier">create_plugin</span><span class="special">();</span> <span class="comment">// Forward declaration</span> 395<span class="special">}</span> <span class="comment">// namespace my_namespace</span> 396 397<span class="identifier">BOOST_DLL_ALIAS</span><span class="special">(</span> 398 <span class="identifier">my_namespace</span><span class="special">::</span><span class="identifier">create_plugin</span><span class="special">,</span> <span class="comment">// <-- this function is exported with...</span> 399 <span class="identifier">create_plugin</span> <span class="comment">// <-- ...this alias name</span> 400<span class="special">)</span> 401</pre> 402<p> 403 </p> 404<p> 405 Main trick here is the alias definition. When linking plugin into the executable, 406 the alias <span class="bold"><strong>must</strong></span> be instantiated in one of 407 the source files of the executable. Otherwise the linker will optimize away 408 our plugin. 409 </p> 410<p> 411 Here's how the implementation of the plugin looks like: 412 </p> 413<p> 414</p> 415<pre class="programlisting"><span class="preprocessor">#include</span> <span class="string">"static_plugin.hpp"</span> <span class="comment">// this is essential, BOOST_SYMBOL_ALIAS must be seen in this file</span> 416 417<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">make_shared</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 418<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 419 420<span class="keyword">namespace</span> <span class="identifier">my_namespace</span> <span class="special">{</span> 421 422<span class="keyword">class</span> <span class="identifier">my_plugin_static</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">my_plugin_api</span> <span class="special">{</span> 423<span class="keyword">public</span><span class="special">:</span> 424 <span class="identifier">my_plugin_static</span><span class="special">()</span> <span class="special">{</span> 425 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Constructing my_plugin_static"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 426 <span class="special">}</span> 427 428 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> 429 <span class="keyword">return</span> <span class="string">"static"</span><span class="special">;</span> 430 <span class="special">}</span> 431 432 <span class="keyword">float</span> <span class="identifier">calculate</span><span class="special">(</span><span class="keyword">float</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">float</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> 433 <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">-</span> <span class="identifier">y</span><span class="special">;</span> 434 <span class="special">}</span> 435 436 <span class="special">~</span><span class="identifier">my_plugin_static</span><span class="special">()</span> <span class="special">{</span> 437 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Destructing my_plugin_static"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 438 <span class="special">}</span> 439<span class="special">};</span> 440 441<span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_plugin_api</span><span class="special">></span> <span class="identifier">create_plugin</span><span class="special">()</span> <span class="special">{</span> 442 <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special"><</span><span class="identifier">my_plugin_static</span><span class="special">>();</span> 443<span class="special">}</span> 444 445<span class="special">}</span> <span class="comment">// namespace my_namespace</span> 446</pre> 447<p> 448 </p> 449<p> 450 Now if we make a static library from source file and link that static library 451 with the following code, we'll be able to import symbols from plugin: 452 </p> 453<p> 454</p> 455<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">shared_library</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for shared_library</span> 456<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">runtime_symbol_info</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for program_location()</span> 457<span class="preprocessor">#include</span> <span class="string">"static_plugin.hpp"</span> <span class="comment">// without this headers some compilers may optimize out the `create_plugin` symbol</span> 458<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 459<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 460 461<span class="keyword">namespace</span> <span class="identifier">dll</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">;</span> 462 463<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 464 <span class="identifier">dll</span><span class="special">::</span><span class="identifier">shared_library</span> <span class="identifier">self</span><span class="special">(</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">program_location</span><span class="special">());</span> 465 466 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Call function"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 467 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_plugin_api</span><span class="special">>()></span> <span class="identifier">creator</span> 468 <span class="special">=</span> <span class="identifier">self</span><span class="special">.</span><span class="identifier">get_alias</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_plugin_api</span><span class="special">>()>(</span><span class="string">"create_plugin"</span><span class="special">);</span> 469 470 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Computed Value: "</span> <span class="special"><<</span> <span class="identifier">creator</span><span class="special">()-></span><span class="identifier">calculate</span><span class="special">(</span><span class="number">2</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">endl</span><span class="special">;</span> 471<span class="special">}</span> 472</pre> 473<p> 474 </p> 475<div class="note"><table border="0" summary="Note"> 476<tr> 477<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> 478<th align="left">Note</th> 479</tr> 480<tr><td align="left" valign="top"><p> 481 Flag '-rdynamic' must be used when linking the plugin into the executable 482 on Linux OS. Otherwise loading symbols from self <span class="bold"><strong>will 483 fail</strong></span>. 484 </p></td></tr> 485</table></div> 486<p> 487 Running the program will output the following: 488 </p> 489<pre class="programlisting">Call function 490Constructing my_plugin_static 491Computed Value: 0 492Destructing my_plugin_static 493</pre> 494<div class="note"><table border="0" summary="Note"> 495<tr> 496<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> 497<th align="left">Note</th> 498</tr> 499<tr><td align="left" valign="top"><p> 500 If we want to make a traditional plugin that is located in a separate shared 501 library, all we need to do is remove the <code class="computeroutput"><span class="preprocessor">#include</span> 502 <span class="string">"static_plugin.hpp"</span></code> line 503 and replace <code class="computeroutput"><span class="identifier">dll</span><span class="special">::</span><span class="identifier">program_location</span><span class="special">()</span></code> 504 with plugin location and name. 505 </p></td></tr> 506</table></div> 507<p> 508 <span class="bold"><strong>Full sources:</strong></span> 509 </p> 510<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 511<li class="listitem"> 512 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial4/static_plugin.hpp" target="_top">example/tutorial4/static_plugin.hpp</a> 513 </li> 514<li class="listitem"> 515 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial4/static_plugin.cpp" target="_top">example/tutorial4/static_plugin.cpp</a> 516 </li> 517<li class="listitem"> 518 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial4/load_self.cpp" target="_top">example/tutorial4/load_self.cpp</a> 519 </li> 520</ul></div> 521<p> 522 <a class="link" href="tutorial.html" title="Tutorial">Back to the Top</a> 523 </p> 524</div> 525<div class="section"> 526<div class="titlepage"><div><div><h3 class="title"> 527<a name="boost_dll.tutorial.symbol_shadowing_problem__linux_"></a><a class="link" href="tutorial.html#boost_dll.tutorial.symbol_shadowing_problem__linux_" title="Symbol shadowing problem (Linux)">Symbol 528 shadowing problem (Linux)</a> 529</h3></div></div></div> 530<p> 531 Let's make an executable, link a plugin into it and attempt to load all the 532 existing plugins: 533 </p> 534<p> 535</p> 536<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">dll</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">;</span> 537 538<span class="keyword">class</span> <span class="identifier">plugins_collector</span> <span class="special">{</span> 539 <span class="comment">// Name => plugin</span> 540 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">::</span><span class="identifier">map</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">dll</span><span class="special">::</span><span class="identifier">shared_library</span><span class="special">></span> <span class="identifier">plugins_t</span><span class="special">;</span> 541 542 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">fs</span><span class="special">::</span><span class="identifier">path</span> <span class="identifier">plugins_directory_</span><span class="special">;</span> 543 <span class="identifier">plugins_t</span> <span class="identifier">plugins_</span><span class="special">;</span> 544 545 <span class="comment">// loads all plugins in plugins_directory_</span> 546 <span class="keyword">void</span> <span class="identifier">load_all</span><span class="special">();</span> 547 548 <span class="comment">// Gets `my_plugin_api` instance using "create_plugin" or "plugin" imports,</span> 549 <span class="comment">// stores plugin with its name in the `plugins_` map.</span> 550 <span class="keyword">void</span> <span class="identifier">insert_plugin</span><span class="special">(</span><span class="identifier">BOOST_RV_REF</span><span class="special">(</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">shared_library</span><span class="special">)</span> <span class="identifier">lib</span><span class="special">);</span> 551 552<span class="keyword">public</span><span class="special">:</span> 553 <span class="identifier">plugins_collector</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">fs</span><span class="special">::</span><span class="identifier">path</span><span class="special">&</span> <span class="identifier">plugins_directory</span><span class="special">)</span> 554 <span class="special">:</span> <span class="identifier">plugins_directory_</span><span class="special">(</span><span class="identifier">plugins_directory</span><span class="special">)</span> 555 <span class="special">{</span> 556 <span class="identifier">load_all</span><span class="special">();</span> 557 <span class="special">}</span> 558 559 <span class="keyword">void</span> <span class="identifier">print_plugins</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span> 560 561 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span> 562 <span class="comment">// ...</span> 563<span class="special">};</span> 564</pre> 565<p> 566 </p> 567<p> 568</p> 569<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">argc</span><span class="special">,</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">argv</span><span class="special">[])</span> <span class="special">{</span> 570 571 <span class="identifier">plugins_collector</span> <span class="identifier">plugins</span><span class="special">(</span><span class="identifier">argv</span><span class="special">[</span><span class="number">1</span><span class="special">]);</span> 572 573 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"\n\nUnique plugins "</span> <span class="special"><<</span> <span class="identifier">plugins</span><span class="special">.</span><span class="identifier">count</span><span class="special">()</span> <span class="special"><<</span> <span class="string">":\n"</span><span class="special">;</span> 574 <span class="identifier">plugins</span><span class="special">.</span><span class="identifier">print_plugins</span><span class="special">();</span> 575 <span class="comment">// ...</span> 576</pre> 577<p> 578 </p> 579<p> 580 With the default flags you'll get a very strange output: 581 </p> 582<pre class="programlisting">Loaded (0x180db60):"/libs/dll/test/libmy_plugin_aggregator.so" 583Constructing my_plugin_static 584Destructing my_plugin_static 585... 586 587Unique plugins 2: 588(0x180db60): static 589(0x180e3b0): sum 590Destructing my_plugin_sum ;o) 591</pre> 592<p> 593 Why <code class="computeroutput"><span class="identifier">my_plugin_static</span></code> was 594 constructed while we were loading <code class="computeroutput"><span class="identifier">my_plugin_aggregator</span></code>? 595 </p> 596<p> 597 That's because function <code class="computeroutput"><span class="identifier">create_plugin</span></code> 598 from <code class="computeroutput"><span class="identifier">libmy_plugin_aggregator</span><span class="special">.</span><span class="identifier">so</span></code> was 599 shadowed by the <code class="computeroutput"><span class="identifier">create_plugin</span></code> 600 function from other plugin. Dynamic linker thought that <code class="computeroutput"><span class="identifier">create_plugin</span></code> 601 was already loaded and there is no need to load it again. 602 </p> 603<div class="warning"><table border="0" summary="Warning"> 604<tr> 605<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../doc/src/images/warning.png"></td> 606<th align="left">Warning</th> 607</tr> 608<tr><td align="left" valign="top"><p> 609 Use "-fvisibility=hidden" flag (at least for plugins) while compiling 610 for POSIX platforms. This flag makes your code more portable ("-fvisibility=hidden" 611 is the default behavior under Windows), reduces size of the binaries and 612 improves binary load time. 613 </p></td></tr> 614</table></div> 615<p> 616 Now if we recompile your example with "-fvisibility=hidden" we'll 617 get the following output: 618 </p> 619<pre class="programlisting">Loaded (0x2406b60):"/libs/dll/test/libmy_plugin_aggregator.so" 620Loaded (0x2407410):"/libs/dll/test/libgetting_started_library.so" 621Constructing my_plugin_sum 622... 623 624Unique plugins 3: 625(0x2406b60): aggregator 626(0x7fd1cadce2c8): static 627(0x24073b0): sum 628Destructing my_plugin_sum ;o) 629</pre> 630<p> 631 <span class="bold"><strong>Full sources:</strong></span> 632 </p> 633<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 634<li class="listitem"> 635 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial5/load_all.cpp" target="_top">example/tutorial5/load_all.cpp</a> 636 </li> 637<li class="listitem"> 638 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial4/static_plugin.cpp" target="_top">example/tutorial4/static_plugin.cpp</a> 639 </li> 640<li class="listitem"> 641 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial2/my_plugin_aggregator.cpp" target="_top">example/tutorial2/my_plugin_aggregator.cpp</a> 642 </li> 643<li class="listitem"> 644 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial1/my_plugin_sum.cpp" target="_top">example/tutorial1/my_plugin_sum.cpp</a> 645 </li> 646</ul></div> 647<p> 648 <a class="link" href="tutorial.html" title="Tutorial">Back to the Top</a> 649 </p> 650</div> 651<div class="section"> 652<div class="titlepage"><div><div><h3 class="title"> 653<a name="boost_dll.tutorial.executing_callbacks_on_library_unload"></a><a class="link" href="tutorial.html#boost_dll.tutorial.executing_callbacks_on_library_unload" title="Executing callbacks on library unload">Executing 654 callbacks on library unload</a> 655</h3></div></div></div> 656<p> 657 Boost.DLL provides no out of the box mechanism for catching library unloads. 658 However such task could be easily implemented. 659 </p> 660<p> 661 All you need to do, is write a simple class that stores callbacks and calls 662 them at destruction: 663 </p> 664<p> 665</p> 666<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">alias</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for BOOST_DLL_ALIAS</span> 667<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 668<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">vector</span><span class="special">></span> 669 670<span class="keyword">namespace</span> <span class="identifier">my_namespace</span> <span class="special">{</span> 671 672<span class="keyword">struct</span> <span class="identifier">on_unload</span> <span class="special">{</span> 673 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="keyword">void</span><span class="special">()></span> <span class="identifier">callback_t</span><span class="special">;</span> 674 <span class="keyword">typedef</span> <span class="identifier">on_unload</span> <span class="identifier">this_type</span><span class="special">;</span> 675 676 <span class="special">~</span><span class="identifier">on_unload</span><span class="special">()</span> <span class="special">{</span> 677 <span class="keyword">for</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="identifier">callbacks_</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> 678 <span class="identifier">callback_t</span><span class="special">&</span> <span class="identifier">function</span> <span class="special">=</span> <span class="identifier">callbacks_</span><span class="special">[</span><span class="identifier">i</span><span class="special">];</span> 679 <span class="identifier">function</span><span class="special">();</span> <span class="comment">// calling the callback</span> 680 <span class="special">}</span> 681 <span class="special">}</span> 682 683 <span class="comment">// not thread safe</span> 684 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">add</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">callback_t</span><span class="special">&</span> <span class="identifier">function</span><span class="special">)</span> <span class="special">{</span> 685 <span class="keyword">static</span> <span class="identifier">this_type</span> <span class="identifier">instance</span><span class="special">;</span> 686 <span class="identifier">instance</span><span class="special">.</span><span class="identifier">callbacks_</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">function</span><span class="special">);</span> 687 <span class="special">}</span> 688 689<span class="keyword">private</span><span class="special">:</span> 690 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="identifier">callback_t</span><span class="special">></span> <span class="identifier">callbacks_</span><span class="special">;</span> 691 <span class="identifier">on_unload</span><span class="special">()</span> <span class="special">{}</span> <span class="comment">// prohibit construction outside of the `add` function</span> 692<span class="special">};</span> 693 694<span class="comment">// Exporting the static "add" function with name "on_unload"</span> 695<span class="identifier">BOOST_DLL_ALIAS</span><span class="special">(</span><span class="identifier">my_namespace</span><span class="special">::</span><span class="identifier">on_unload</span><span class="special">::</span><span class="identifier">add</span><span class="special">,</span> <span class="identifier">on_unload</span><span class="special">)</span> 696 697<span class="special">}</span> <span class="comment">// namespace my_namespace</span> 698</pre> 699<p> 700 </p> 701<p> 702 In the example above <code class="computeroutput"><span class="identifier">my_namespace</span><span class="special">::</span><span class="identifier">on_unload</span></code> 703 is a singleton structure that holds a vector of callbacks and calls all the 704 callbacks at destruction. 705 </p> 706<p> 707 Now we can load this library and provide a callback: 708 </p> 709<p> 710</p> 711<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">import</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 712<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 713<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 714 715<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="keyword">void</span><span class="special">()></span> <span class="identifier">callback_t</span><span class="special">;</span> 716 717<span class="keyword">void</span> <span class="identifier">print_unloaded</span><span class="special">()</span> <span class="special">{</span> 718 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"unloaded"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 719<span class="special">}</span> 720 721<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">argc</span><span class="special">,</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">argv</span><span class="special">[])</span> <span class="special">{</span> 722 <span class="comment">// argv[1] contains full path to our plugin library</span> 723 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">fs</span><span class="special">::</span><span class="identifier">path</span> <span class="identifier">shared_library_path</span> <span class="special">=</span> <span class="identifier">argv</span><span class="special">[</span><span class="number">1</span><span class="special">];</span> 724 725 <span class="comment">// loading library and getting a function from it</span> 726 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="keyword">void</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">callback_t</span><span class="special">&)></span> <span class="identifier">on_unload</span> 727 <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">import_alias</span><span class="special"><</span><span class="keyword">void</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">callback_t</span><span class="special">&)>(</span> 728 <span class="identifier">shared_library_path</span><span class="special">,</span> <span class="string">"on_unload"</span> 729 <span class="special">);</span> 730 731 <span class="identifier">on_unload</span><span class="special">(&</span><span class="identifier">print_unloaded</span><span class="special">);</span> <span class="comment">// adding a callback</span> 732 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Before library unload."</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 733 734 <span class="comment">// Releasing last reference to the library, so that it gets unloaded</span> 735 <span class="identifier">on_unload</span><span class="special">.</span><span class="identifier">clear</span><span class="special">();</span> 736 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"After library unload."</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 737<span class="special">}</span> 738</pre> 739<p> 740 </p> 741<p> 742 If we run the example we'll get the following output: 743 </p> 744<pre class="programlisting">Before library unload. 745unloaded 746After library unload. 747</pre> 748<p> 749 <span class="bold"><strong>Full sources:</strong></span> 750 </p> 751<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 752<li class="listitem"> 753 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial6/on_unload_lib.cpp" target="_top">example/tutorial6/on_unload_lib.cpp</a> 754 </li> 755<li class="listitem"> 756 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial6/tutorial6.cpp" target="_top">example/tutorial6/tutorial6.cpp</a> 757 </li> 758</ul></div> 759<p> 760 <a class="link" href="tutorial.html" title="Tutorial">Back to the Top</a> 761 </p> 762</div> 763<div class="section"> 764<div class="titlepage"><div><div><h3 class="title"> 765<a name="boost_dll.tutorial.querying_libraries_for_symbols"></a><a class="link" href="tutorial.html#boost_dll.tutorial.querying_libraries_for_symbols" title="Querying libraries for symbols">Querying 766 libraries for symbols</a> 767</h3></div></div></div> 768<p> 769 Situation when we do not know names of functions in plugin could occur. In 770 that case querying library could be useful. 771 </p> 772<p> 773 Imagine the situation: we have a project called 'Anna' that is capable of 774 loading and using plugins that contain functions with signature <code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="keyword">const</span> 775 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&)</span></code>. 776 We do not know function names, but wish to find out them somehow. 777 </p> 778<p> 779 Solution would be pretty simple. Let's agree with plugin developers, that 780 they can name functions as they like, but all the plugin functions aliases 781 must be located in section named 'Anna': 782 </p> 783<p> 784</p> 785<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">alias</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for BOOST_DLL_ALIAS_SECTIONED</span> 786<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 787<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">string</span><span class="special">></span> 788 789<span class="keyword">void</span> <span class="identifier">print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">s</span><span class="special">)</span> <span class="special">{</span> 790 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Hello, "</span> <span class="special"><<</span> <span class="identifier">s</span> <span class="special"><<</span> <span class="char">'!'</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 791<span class="special">}</span> 792 793<span class="identifier">BOOST_DLL_ALIAS_SECTIONED</span><span class="special">(</span><span class="identifier">print</span><span class="special">,</span> <span class="identifier">print_hello</span><span class="special">,</span> <span class="identifier">Anna</span><span class="special">)</span> 794</pre> 795<p> 796 </p> 797<p> 798</p> 799<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">alias</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for BOOST_DLL_ALIAS_SECTIONED</span> 800<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">string</span><span class="special">></span> 801<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 802 803<span class="keyword">void</span> <span class="identifier">print_howdy</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">s</span><span class="special">)</span> <span class="special">{</span> 804 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"How're you doing, "</span> <span class="special"><<</span> <span class="identifier">s</span> <span class="special"><<</span> <span class="char">'?'</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 805<span class="special">}</span> 806 807<span class="keyword">void</span> <span class="identifier">print_bored</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">s</span><span class="special">)</span> <span class="special">{</span> 808 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Are you bored, "</span> <span class="special"><<</span> <span class="identifier">s</span> <span class="special"><<</span> <span class="char">'?'</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 809<span class="special">}</span> 810 811<span class="identifier">BOOST_DLL_ALIAS_SECTIONED</span><span class="special">(</span><span class="identifier">print_howdy</span><span class="special">,</span> <span class="identifier">howdy</span><span class="special">,</span> <span class="identifier">Anna</span><span class="special">)</span> 812<span class="identifier">BOOST_DLL_ALIAS_SECTIONED</span><span class="special">(</span><span class="identifier">print_bored</span><span class="special">,</span> <span class="identifier">are_you_bored</span><span class="special">,</span> <span class="identifier">Anna</span><span class="special">)</span> 813</pre> 814<p> 815 </p> 816<p> 817 Now we can easily get those functions using the <code class="computeroutput"><a class="link" href="../boost/dll/library_info.html" title="Class library_info">boost::dll::library_info</a></code>: 818 </p> 819<p> 820</p> 821<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">shared_library</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 822<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">library_info</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 823<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 824 825<span class="keyword">void</span> <span class="identifier">load_and_execute</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">fs</span><span class="special">::</span><span class="identifier">path</span> <span class="identifier">libraries</span><span class="special">[],</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">libs_count</span><span class="special">)</span> <span class="special">{</span> 826 <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">username</span> <span class="special">=</span> <span class="string">"User"</span><span class="special">;</span> 827 828 <span class="keyword">for</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="identifier">libs_count</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> 829 <span class="comment">// Class `library_info` can extract information from a library</span> 830 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">library_info</span> <span class="identifier">inf</span><span class="special">(</span><span class="identifier">libraries</span><span class="special">[</span><span class="identifier">i</span><span class="special">]);</span> 831 832 <span class="comment">// Getting symbols exported from 'Anna' section</span> 833 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</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">exports</span> <span class="special">=</span> <span class="identifier">inf</span><span class="special">.</span><span class="identifier">symbols</span><span class="special">(</span><span class="string">"Anna"</span><span class="special">);</span> 834 835 <span class="comment">// Loading library and importing symbols from it</span> 836 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">shared_library</span> <span class="identifier">lib</span><span class="special">(</span><span class="identifier">libraries</span><span class="special">[</span><span class="identifier">i</span><span class="special">]);</span> 837 <span class="keyword">for</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">j</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">j</span> <span class="special"><</span> <span class="identifier">exports</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span> <span class="special">++</span><span class="identifier">j</span><span class="special">)</span> <span class="special">{</span> 838 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"\nFunction '"</span> <span class="special"><<</span> <span class="identifier">exports</span><span class="special">[</span><span class="identifier">j</span><span class="special">]</span> <span class="special"><<</span> <span class="string">"' prints:\n\t"</span><span class="special">;</span> 839 <span class="identifier">lib</span><span class="special">.</span><span class="identifier">get_alias</span><span class="special"><</span><span class="keyword">void</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&)>(</span><span class="identifier">exports</span><span class="special">[</span><span class="identifier">j</span><span class="special">])</span> <span class="comment">// importing function</span> 840 <span class="special">(</span><span class="identifier">username</span><span class="special">);</span> <span class="comment">// calling function</span> 841 <span class="special">}</span> 842 <span class="special">}</span> 843<span class="special">}</span> 844</pre> 845<p> 846 </p> 847<p> 848 If we run the example we'll get the following output: 849 </p> 850<pre class="programlisting">Function 'print_hello' prints: 851 Hello, User! 852 853Function 'are_you_bored' prints: 854 Are you bored, User? 855 856Function 'howdy' prints: 857 How're you doing, User? 858</pre> 859<div class="note"><table border="0" summary="Note"> 860<tr> 861<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> 862<th align="left">Note</th> 863</tr> 864<tr><td align="left" valign="top"><p> 865 <code class="computeroutput"><span class="identifier">BOOST_DLL_ALIAS</span></code> macro by 866 default places all the aliases into the "boostdll" section. 867 </p></td></tr> 868</table></div> 869<p> 870 <span class="bold"><strong>Full sources:</strong></span> 871 </p> 872<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 873<li class="listitem"> 874 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial7/library1.cpp" target="_top">example/tutorial7/library1.cpp</a> 875 </li> 876<li class="listitem"> 877 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial7/library2.cpp" target="_top">example/tutorial7/library2.cpp</a> 878 </li> 879<li class="listitem"> 880 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial7/tutorial7.cpp" target="_top">example/tutorial7/tutorial7.cpp</a> 881 </li> 882</ul></div> 883<p> 884 <a class="link" href="tutorial.html" title="Tutorial">Back to the Top</a> 885 </p> 886</div> 887<div class="section"> 888<div class="titlepage"><div><div><h3 class="title"> 889<a name="boost_dll.tutorial.advanced_library_reference_counting"></a><a class="link" href="tutorial.html#boost_dll.tutorial.advanced_library_reference_counting" title="Advanced library reference counting">Advanced 890 library reference counting</a> 891</h3></div></div></div> 892<p> 893 As noted in documentation to the <code class="computeroutput"><a class="link" href="../boost/dll/import.html" title="Function import">boost::dll::import</a></code> 894 variables and functions returned from those functions hold a reference to 895 the shared library. However nested objects and objects that are returned 896 by <code class="computeroutput"><span class="identifier">import</span><span class="special">*</span></code> 897 functions do not hold a reference to the shared library. There's no way to 898 solve this issue on the Boost.DLL library level, but you can take care of 899 this problem by your own. Here's an example how this could be done. 900 </p> 901<p> 902 In this example we'll be importing function that constructs an instance of 903 plugin and binding that instance to shared_library. 904 </p> 905<p> 906 First of all we need to define a new plugin api: 907 </p> 908<p> 909</p> 910<pre class="programlisting"><span class="preprocessor">#include</span> <span class="string">"../tutorial_common/my_plugin_api.hpp"</span> 911<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">config</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 912 913<span class="keyword">class</span> <span class="identifier">my_refcounting_api</span><span class="special">:</span> <span class="keyword">public</span> <span class="identifier">my_plugin_api</span> <span class="special">{</span> 914<span class="keyword">public</span><span class="special">:</span> 915 <span class="comment">// Returns path to shared object that holds a plugin.</span> 916 <span class="comment">// Must be instantiated in plugin.</span> 917 <span class="keyword">virtual</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">fs</span><span class="special">::</span><span class="identifier">path</span> <span class="identifier">location</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> 918<span class="special">};</span> 919</pre> 920<p> 921 </p> 922<p> 923 This API does not differ much from the previous one. Only one abstract method 924 was added. 925 </p> 926<p> 927 Now let's define the plugin: 928 </p> 929<p> 930</p> 931<pre class="programlisting"><span class="preprocessor">#include</span> <span class="string">"refcounting_plugin.hpp"</span> 932<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">runtime_symbol_info</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for this_line_location()</span> 933 934<span class="keyword">namespace</span> <span class="identifier">my_namespace</span> <span class="special">{</span> 935 936<span class="keyword">class</span> <span class="identifier">my_plugin_refcounting</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">my_refcounting_api</span> <span class="special">{</span> 937<span class="keyword">public</span><span class="special">:</span> 938 <span class="comment">// Must be instantiated in plugin</span> 939 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">fs</span><span class="special">::</span><span class="identifier">path</span> <span class="identifier">location</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> 940 <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">this_line_location</span><span class="special">();</span> <span class="comment">// location of this plugin</span> 941 <span class="special">}</span> 942 943 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> 944 <span class="keyword">return</span> <span class="string">"refcounting"</span><span class="special">;</span> 945 <span class="special">}</span> 946 947 <span class="comment">// ...</span> 948<span class="special">};</span> 949 950<span class="special">}</span> <span class="comment">// namespace my_namespace</span> 951 952<span class="comment">// Factory method. Returns *simple pointer*!</span> 953<span class="identifier">my_refcounting_api</span><span class="special">*</span> <span class="identifier">create</span><span class="special">()</span> <span class="special">{</span> 954 <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">my_namespace</span><span class="special">::</span><span class="identifier">my_plugin_refcounting</span><span class="special">();</span> 955<span class="special">}</span> 956</pre> 957<p> 958 </p> 959<p> 960 This plugin does not differ much from our previous examples except the additional 961 method that calls <code class="computeroutput"><a class="link" href="../boost/dll/this_line_location.html" title="Function this_line_location">boost::dll::this_line_location</a></code> 962 and <code class="computeroutput"><span class="identifier">create</span><span class="special">()</span></code> 963 function that returns a simple pointer instead of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span></code>. 964 </p> 965<p> 966 Now lets make a function that binds a newly created instance of <code class="computeroutput"><span class="identifier">my_refcounting_api</span></code> to a shared library: 967 </p> 968<p> 969</p> 970<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">shared_ptr</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 971<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">make_shared</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 972<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">shared_library</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 973 974<span class="keyword">struct</span> <span class="identifier">library_holding_deleter</span> <span class="special">{</span> 975 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">shared_library</span><span class="special">></span> <span class="identifier">lib_</span><span class="special">;</span> 976 977 <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">my_refcounting_api</span><span class="special">*</span> <span class="identifier">p</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> 978 <span class="keyword">delete</span> <span class="identifier">p</span><span class="special">;</span> 979 <span class="special">}</span> 980<span class="special">};</span> 981 982<span class="keyword">inline</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_refcounting_api</span><span class="special">></span> <span class="identifier">bind</span><span class="special">(</span><span class="identifier">my_refcounting_api</span><span class="special">*</span> <span class="identifier">plugin</span><span class="special">)</span> <span class="special">{</span> 983 <span class="comment">// getting location of the shared library that holds the plugin</span> 984 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">fs</span><span class="special">::</span><span class="identifier">path</span> <span class="identifier">location</span> <span class="special">=</span> <span class="identifier">plugin</span><span class="special">-></span><span class="identifier">location</span><span class="special">();</span> 985 986 <span class="comment">// `make_shared` is an efficient way to create a shared pointer</span> 987 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">shared_library</span><span class="special">></span> <span class="identifier">lib</span> 988 <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">shared_library</span><span class="special">>(</span><span class="identifier">location</span><span class="special">);</span> 989 990 <span class="identifier">library_holding_deleter</span> <span class="identifier">deleter</span><span class="special">;</span> 991 <span class="identifier">deleter</span><span class="special">.</span><span class="identifier">lib_</span> <span class="special">=</span> <span class="identifier">lib</span><span class="special">;</span> 992 993 <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_refcounting_api</span><span class="special">>(</span> 994 <span class="identifier">plugin</span><span class="special">,</span> <span class="identifier">deleter</span> 995 <span class="special">);</span> 996<span class="special">}</span> 997</pre> 998<p> 999 </p> 1000<p> 1001 In <code class="computeroutput"><span class="identifier">bind</span></code> method we call <code class="computeroutput"><span class="identifier">plugin</span><span class="special">-></span><span class="identifier">location</span><span class="special">()</span></code>. 1002 This call results in a call to <code class="computeroutput"><a class="link" href="../boost/dll/this_line_location.html" title="Function this_line_location">boost::dll::this_line_location</a></code> 1003 and returns the plugin location. Then a <code class="computeroutput"><span class="identifier">shared_ptr</span></code> 1004 that holds a <code class="computeroutput"><span class="identifier">shared_library</span></code> 1005 is created using the <code class="computeroutput"><span class="identifier">make_shared</span></code> 1006 call. 1007 </p> 1008<p> 1009 After that we construct a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_refcounting_api</span><span class="special">></span></code> with a <code class="computeroutput"><span class="identifier">library_holding_deleter</span></code> 1010 that keeps an instance of the shared library. 1011 </p> 1012<div class="note"><table border="0" summary="Note"> 1013<tr> 1014<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> 1015<th align="left">Note</th> 1016</tr> 1017<tr><td align="left" valign="top"><p> 1018 Use <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_ptr</span><span class="special"><</span><span class="identifier">my_refcounting_api</span><span class="special">></span></code> 1019 instead of <code class="computeroutput"><span class="identifier">my_refcounting_api</span><span class="special">*</span></code> in production code to avoid memory leaks 1020 when <code class="computeroutput"><span class="identifier">plugin</span><span class="special">-></span><span class="identifier">location</span><span class="special">()</span></code> 1021 throws or when some other class rises an exception. 1022 </p></td></tr> 1023</table></div> 1024<p> 1025 That's it, now we can get instance of a plugin: 1026 </p> 1027<p> 1028</p> 1029<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">import</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 1030<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 1031<span class="keyword">inline</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_refcounting_api</span><span class="special">></span> <span class="identifier">get_plugin</span><span class="special">(</span> 1032 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">fs</span><span class="special">::</span><span class="identifier">path</span> <span class="identifier">path</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">func_name</span><span class="special">)</span> 1033<span class="special">{</span> 1034 <span class="keyword">typedef</span> <span class="identifier">my_refcounting_api</span><span class="special">*(</span><span class="identifier">func_t</span><span class="special">)();</span> 1035 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="identifier">func_t</span><span class="special">></span> <span class="identifier">creator</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">import_alias</span><span class="special"><</span><span class="identifier">func_t</span><span class="special">>(</span> 1036 <span class="identifier">path</span><span class="special">,</span> 1037 <span class="identifier">func_name</span><span class="special">,</span> 1038 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">load_mode</span><span class="special">::</span><span class="identifier">append_decorations</span> <span class="comment">// will be ignored for executable</span> 1039 <span class="special">);</span> 1040 1041 <span class="comment">// `plugin` does not hold a reference to shared library. If `creator` will go out of scope, </span> 1042 <span class="comment">// then `plugin` can not be used.</span> 1043 <span class="identifier">my_refcounting_api</span><span class="special">*</span> <span class="identifier">plugin</span> <span class="special">=</span> <span class="identifier">creator</span><span class="special">();</span> 1044 1045 <span class="comment">// Returned variable holds a reference to </span> 1046 <span class="comment">// shared_library and it is safe to use it.</span> 1047 <span class="keyword">return</span> <span class="identifier">bind</span><span class="special">(</span> <span class="identifier">plugin</span> <span class="special">);</span> 1048 1049 <span class="comment">// `creator` goes out of scope here and will be destroyed.</span> 1050<span class="special">}</span> 1051</pre> 1052<p> 1053 </p> 1054<p> 1055 Here's how it <code class="computeroutput"><span class="identifier">main</span><span class="special">()</span></code> 1056 function look like: 1057 </p> 1058<div class="informaltable"><table class="table"> 1059<colgroup> 1060<col> 1061<col> 1062<col> 1063</colgroup> 1064<thead><tr> 1065<th> 1066 </th> 1067<th> 1068 <p> 1069 Runtime plugin load 1070 </p> 1071 </th> 1072<th> 1073 <p> 1074 Plugin was linked in 1075 </p> 1076 </th> 1077</tr></thead> 1078<tbody> 1079<tr> 1080<td> 1081 <p> 1082 Code 1083 </p> 1084 </td> 1085<td> 1086 <p> 1087</p> 1088<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 1089<span class="preprocessor">#include</span> <span class="string">"refcounting_api.hpp"</span> 1090 1091<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">argc</span><span class="special">,</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">argv</span><span class="special">[])</span> <span class="special">{</span> 1092 1093 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_refcounting_api</span><span class="special">></span> <span class="identifier">plugin</span> <span class="special">=</span> <span class="identifier">get_plugin</span><span class="special">(</span> 1094 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">fs</span><span class="special">::</span><span class="identifier">path</span><span class="special">(</span><span class="identifier">argv</span><span class="special">[</span><span class="number">1</span><span class="special">])</span> <span class="special">/</span> <span class="string">"refcounting_plugin"</span><span class="special">,</span> 1095 <span class="string">"create_refc_plugin"</span> 1096 <span class="special">);</span> 1097 1098 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Plugin name: "</span> <span class="special"><<</span> <span class="identifier">plugin</span><span class="special">-></span><span class="identifier">name</span><span class="special">()</span> 1099 <span class="special"><<</span> <span class="string">", \nlocation: "</span> <span class="special"><<</span> <span class="identifier">plugin</span><span class="special">-></span><span class="identifier">location</span><span class="special">()</span> 1100 <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1101<span class="special">}</span> 1102</pre> 1103<p> 1104 </p> 1105 </td> 1106<td> 1107 <p> 1108</p> 1109<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">runtime_symbol_info</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// program_location()</span> 1110<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 1111<span class="preprocessor">#include</span> <span class="string">"refcounting_plugin.hpp"</span> 1112 1113<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 1114 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">my_refcounting_api</span><span class="special">></span> <span class="identifier">plugin</span> <span class="special">=</span> <span class="identifier">get_plugin</span><span class="special">(</span> 1115 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">program_location</span><span class="special">(),</span> 1116 <span class="string">"create_refc_plugin"</span> 1117 <span class="special">);</span> 1118 1119 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Plugin name: "</span> <span class="special"><<</span> <span class="identifier">plugin</span><span class="special">-></span><span class="identifier">name</span><span class="special">()</span> 1120 <span class="special"><<</span> <span class="string">", \nlocation: "</span> <span class="special"><<</span> <span class="identifier">plugin</span><span class="special">-></span><span class="identifier">location</span><span class="special">()</span> 1121 <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1122<span class="special">}</span> 1123</pre> 1124<p> 1125 </p> 1126 </td> 1127</tr> 1128<tr> 1129<td> 1130 <p> 1131 Output 1132 </p> 1133 </td> 1134<td> 1135<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">Plugin name: refcounting, 1136location: "/libs/dll/librefcounting_plugin.so"</pre> 1137 </td> 1138<td> 1139<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">Plugin name: refcounting, 1140location: "/tutorial8_static"</pre> 1141 </td> 1142</tr> 1143</tbody> 1144</table></div> 1145<p> 1146 <span class="bold"><strong>Full sources:</strong></span> 1147 </p> 1148<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 1149<li class="listitem"> 1150 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial8/refcounting_api.hpp" target="_top">example/tutorial8/refcounting_api.hpp</a> 1151 </li> 1152<li class="listitem"> 1153 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial8/refcounting_plugin.hpp" target="_top">example/tutorial8/refcounting_plugin.hpp</a> 1154 </li> 1155<li class="listitem"> 1156 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial8/refcounting_plugin.cpp" target="_top">example/tutorial8/refcounting_plugin.cpp</a> 1157 </li> 1158<li class="listitem"> 1159 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial8/tutorial8.cpp" target="_top">example/tutorial8/tutorial8.cpp</a> 1160 </li> 1161<li class="listitem"> 1162 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial8/tutorial8_static.cpp" target="_top">example/tutorial8/tutorial8_static.cpp</a> 1163 </li> 1164</ul></div> 1165<p> 1166 <a class="link" href="tutorial.html" title="Tutorial">Back to the Top</a> 1167 </p> 1168</div> 1169<div class="section"> 1170<div class="titlepage"><div><div><h3 class="title"> 1171<a name="boost_dll.tutorial.importing_a_c_function_from_windows_dll"></a><a class="link" href="tutorial.html#boost_dll.tutorial.importing_a_c_function_from_windows_dll" title="Importing a C function from Windows dll">Importing 1172 a C function from Windows dll</a> 1173</h3></div></div></div> 1174<p> 1175 This a trivial example, but it has one tricky place. When you are importing 1176 a C function by <span class="bold"><strong>it's name</strong></span> you must use 1177 <code class="computeroutput"><a class="link" href="../boost/dll/import.html" title="Function import">boost::dll::import</a></code>, 1178 not <code class="computeroutput"><a class="link" href="../boost/dll/import_alias.html" title="Function import_alias">boost::dll::import_alias</a></code>: 1179 </p> 1180<p> 1181</p> 1182<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">import</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for dll::import</span> 1183<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">dll</span><span class="special">/</span><span class="identifier">shared_library</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for dll::shared_library</span> 1184<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 1185<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 1186<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">windows</span><span class="special">.</span><span class="identifier">h</span><span class="special">></span> 1187 1188<span class="keyword">namespace</span> <span class="identifier">dll</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">;</span> 1189 1190<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span> 1191 <span class="keyword">typedef</span> <span class="identifier">HANDLE</span><span class="special">(</span><span class="identifier">__stdcall</span> <span class="identifier">GetStdHandle_t</span><span class="special">)(</span><span class="identifier">DWORD</span> <span class="special">);</span> <span class="comment">// function signature with calling convention</span> 1192 1193 <span class="comment">// OPTION #0, requires C++11 compatible compiler that understands GetStdHandle_t signature.</span> 1194 1195 <span class="keyword">auto</span> <span class="identifier">get_std_handle</span> <span class="special">=</span> <span class="identifier">dll</span><span class="special">::</span><span class="identifier">import</span><span class="special"><</span><span class="identifier">GetStdHandle_t</span><span class="special">>(</span> 1196 <span class="string">"Kernel32.dll"</span><span class="special">,</span> 1197 <span class="string">"GetStdHandle"</span><span class="special">,</span> 1198 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">dll</span><span class="special">::</span><span class="identifier">load_mode</span><span class="special">::</span><span class="identifier">search_system_folders</span> 1199 <span class="special">);</span> 1200 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"0.0 GetStdHandle() returned "</span> <span class="special"><<</span> <span class="identifier">get_std_handle</span><span class="special">(</span><span class="identifier">STD_OUTPUT_HANDLE</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1201 1202 <span class="comment">// You may put the `get_std_handle` into boost::function<>. But boost::function<Signature> can not compile with</span> 1203 <span class="comment">// Signature template parameter that contains calling conventions, so you'll have to remove the calling convention.</span> 1204 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="identifier">HANDLE</span><span class="special">(</span><span class="identifier">DWORD</span><span class="special">)></span> <span class="identifier">get_std_handle2</span> <span class="special">=</span> <span class="identifier">get_std_handle</span><span class="special">;</span> 1205 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"0.1 GetStdHandle() returned "</span> <span class="special"><<</span> <span class="identifier">get_std_handle2</span><span class="special">(</span><span class="identifier">STD_OUTPUT_HANDLE</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1206 1207 1208 <span class="comment">// OPTION #1, does not require C++11. But without C++11 dll::import<> can not handle calling conventions,</span> 1209 <span class="comment">// so you'll need to hand write the import.</span> 1210 <span class="identifier">dll</span><span class="special">::</span><span class="identifier">shared_library</span> <span class="identifier">lib</span><span class="special">(</span><span class="string">"Kernel32.dll"</span><span class="special">,</span> <span class="identifier">dll</span><span class="special">::</span><span class="identifier">load_mode</span><span class="special">::</span><span class="identifier">search_system_folders</span><span class="special">);</span> 1211 <span class="identifier">GetStdHandle_t</span><span class="special">&</span> <span class="identifier">func</span> <span class="special">=</span> <span class="identifier">lib</span><span class="special">.</span><span class="identifier">get</span><span class="special"><</span><span class="identifier">GetStdHandle_t</span><span class="special">>(</span><span class="string">"GetStdHandle"</span><span class="special">);</span> 1212 1213 <span class="comment">// Here `func` does not keep a reference to `lib`, you'll have to deal with that on your own.</span> 1214 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"1.0 GetStdHandle() returned "</span> <span class="special"><<</span> <span class="identifier">func</span><span class="special">(</span><span class="identifier">STD_OUTPUT_HANDLE</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 1215 1216 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> 1217<span class="special">}</span> 1218</pre> 1219<p> 1220 </p> 1221<p> 1222 <span class="bold"><strong>Full sources:</strong></span> 1223 </p> 1224<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> 1225 <a href="https://github.com/apolukhin/Boost.DLL/blob/develop/example/tutorial9/tutorial9.cpp" target="_top">example/tutorial9/tutorial9.cpp</a> 1226 </li></ul></div> 1227<p> 1228 <a class="link" href="tutorial.html" title="Tutorial">Back to the Top</a> 1229 </p> 1230</div> 1231</div> 1232<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 1233<td align="left"></td> 1234<td align="right"><div class="copyright-footer">Copyright © 2014 Renato Tegon Forti, Antony Polukhin<br>Copyright © 2015 Antony Polukhin<br>Copyright © 2016 Antony Polukhin, Klemens Morgenstern<br>Copyright © 2017-2019 Antony Polukhin<p> 1235 Distributed under the Boost Software License, Version 1.0. (See accompanying 1236 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 1237 </p> 1238</div></td> 1239</tr></table> 1240<hr> 1241<div class="spirit-nav"> 1242<a accesskey="p" href="getting_started.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_dll.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="mangled_import.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> 1243</div> 1244</body> 1245</html> 1246