421 lines
38 KiB
HTML
421 lines
38 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
<html>
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
<title>Mangled Import</title>
|
||
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
|
||
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
|
||
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
|
||
<link rel="up" href="../boost_dll.html" title="Chapter 14. Boost.DLL">
|
||
<link rel="prev" href="tutorial.html" title="Tutorial">
|
||
<link rel="next" href="missuses.html" title="Missuses">
|
||
</head>
|
||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||
<table cellpadding="2" width="100%"><tr>
|
||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
|
||
<td align="center"><a href="../../../index.html">Home</a></td>
|
||
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
|
||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||
<td align="center"><a href="../../../more/index.htm">More</a></td>
|
||
</tr></table>
|
||
<hr>
|
||
<div class="spirit-nav">
|
||
<a accesskey="p" href="tutorial.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="missuses.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||
<a name="boost_dll.mangled_import"></a><a class="link" href="mangled_import.html" title="Mangled Import">Mangled Import</a>
|
||
</h2></div></div></div>
|
||
<div class="toc"><dl class="toc">
|
||
<dt><span class="section"><a href="mangled_import.html#boost_dll.mangled_import.support___requirements">Support
|
||
& Requirements</a></span></dt>
|
||
<dt><span class="section"><a href="mangled_import.html#boost_dll.mangled_import.mangled_import_example">Mangled
|
||
Import Example</a></span></dt>
|
||
<dt><span class="section"><a href="mangled_import.html#boost_dll.mangled_import.class_import">Class Import</a></span></dt>
|
||
<dt><span class="section"><a href="mangled_import.html#boost_dll.mangled_import.overloading_qualifiers">Overloading
|
||
qualifiers</a></span></dt>
|
||
</dl></div>
|
||
<p>
|
||
This section describes the experimental feature of allowing the import of mangled
|
||
symbols from an dll. While this feature is unique to this library and looks
|
||
quite promising, it is not throroughly tested and thus not considered stable.
|
||
</p>
|
||
<p>
|
||
As a short example we can import the following functions quite easily:
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="comment">//library.dll</span>
|
||
<span class="keyword">namespace</span> <span class="identifier">foo</span> <span class="special">{</span>
|
||
<span class="keyword">int</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">int</span><span class="special">);</span>
|
||
<span class="keyword">double</span> <span class="identifier">bar</span><span class="special">(</span><span class="keyword">double</span><span class="special">);</span>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
And the import looks like this:
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">f1</span> <span class="special">=</span> <span class="identifier">import_mangled</span><span class="special"><</span><span class="keyword">int</span><span class="special">(</span><span class="keyword">int</span><span class="special">)>(</span><span class="string">"library.dll"</span><span class="special">,</span> <span class="string">"foo::bar"</span><span class="special">);</span>
|
||
<span class="keyword">auto</span> <span class="identifier">f2</span> <span class="special">=</span> <span class="identifier">import_mangled</span><span class="special"><</span><span class="keyword">double</span><span class="special">(</span><span class="keyword">double</span><span class="special">)>(</span><span class="string">"library.dll"</span><span class="special">,</span> <span class="string">"foo::bar"</span><span class="special">);</span>
|
||
<span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">f1</span><span class="special">(</span><span class="number">42</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">endl</span><span class="special">;</span>
|
||
<span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">f2</span><span class="special">(</span><span class="number">3.2</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">endl</span><span class="special">;</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_dll.mangled_import.support___requirements"></a><a class="link" href="mangled_import.html#boost_dll.mangled_import.support___requirements" title="Support & Requirements">Support
|
||
& Requirements</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
Currently, the Itanium ABI and the MSVC ABI are implemented. The MSVC ABI
|
||
requires boost.spirit.x3 support, allowing only the usage of MSVC 2015. The
|
||
Itanium API requires C++11.
|
||
</p>
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||
<li class="listitem">
|
||
Gcc
|
||
</li>
|
||
<li class="listitem">
|
||
Clang
|
||
</li>
|
||
<li class="listitem">
|
||
MSVC 2015
|
||
</li>
|
||
<li class="listitem">
|
||
Intel C++
|
||
</li>
|
||
</ul></div>
|
||
<p>
|
||
The Itanium API does not import the return type of functions, nor the type
|
||
of global variables.
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_dll.mangled_import.mangled_import_example"></a><a class="link" href="mangled_import.html#boost_dll.mangled_import.mangled_import_example" title="Mangled Import Example">Mangled
|
||
Import Example</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
The core of the mangled import is the <code class="computeroutput">smart_library</code>
|
||
class. It can import functions and variables in their mangled form; to do
|
||
this, the smart_library reads the entire outline of the library and demangles
|
||
every entry point in it. That also means, that this class should only be
|
||
constructed once.
|
||
</p>
|
||
<p>
|
||
In order to import all the methods in the following library, we will use
|
||
the <code class="computeroutput">smart_library</code> .
|
||
</p>
|
||
<p>
|
||
The first thing to do when creating your own plugins is define the plugin
|
||
interface. There is an example of an abstract class that will be our plugin
|
||
API:
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">string</span><span class="special">></span>
|
||
|
||
<span class="keyword">namespace</span> <span class="identifier">space</span> <span class="special">{</span>
|
||
|
||
<span class="keyword">class</span> <span class="identifier">BOOST_SYMBOL_EXPORT</span> <span class="identifier">my_plugin</span>
|
||
<span class="special">{</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">public</span><span class="special">:</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="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="keyword">int</span> <span class="identifier">calculate</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">y</span><span class="special">);</span>
|
||
<span class="keyword">static</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">();</span>
|
||
<span class="identifier">my_plugin</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">name</span><span class="special">);</span>
|
||
<span class="identifier">my_plugin</span><span class="special">();</span>
|
||
<span class="special">~</span><span class="identifier">my_plugin_api</span><span class="special">();</span>
|
||
<span class="keyword">static</span> <span class="keyword">int</span> <span class="identifier">value</span><span class="special">;</span>
|
||
<span class="special">};</span>
|
||
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
Alright, now we have the definition for the plugin, so we use it in the following
|
||
full-fleshed example. Mind that there is a more convenient solution to import
|
||
member-functions which will be discussed later on. This example shows however
|
||
what the <code class="computeroutput">smart_lib</code> provides as features.
|
||
</p>
|
||
<p>
|
||
At first we setup the smart library. Mind that the alias class is needed
|
||
to provide a type-alias for the my_plugin.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<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">smart_library</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> <span class="comment">// for import_alias</span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">memory</span><span class="special">></span>
|
||
|
||
<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>
|
||
|
||
<span class="keyword">struct</span> <span class="identifier">alias</span><span class="special">;</span>
|
||
|
||
<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>
|
||
|
||
<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>
|
||
<span class="identifier">dll</span><span class="special">::</span><span class="identifier">smart_lib</span> <span class="identifier">lib</span><span class="special">(</span><span class="identifier">lib_path</span><span class="special">);</span> <span class="comment">// smart library instance</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
In order to create the class, we will need to allocate memory. That of course
|
||
means, that we need to know the size; unfortunately it is not exported into
|
||
the dll, so we added the static size function for export. Static are used
|
||
as plain functions.
|
||
</p>
|
||
<p>
|
||
So we import it, call it and allocate memory.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">size_f</span> <span class="special">=</span> <span class="identifier">lib</span><span class="special">.</span><span class="identifier">get_function</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">()>(</span><span class="string">"space::my_plugin::size"</span><span class="special">);</span> <span class="comment">//get the size function</span>
|
||
|
||
<span class="keyword">auto</span> <span class="identifier">size</span> <span class="special">=</span> <span class="identifier">size_f</span><span class="special">();</span> <span class="comment">// get the size of the class</span>
|
||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_ptr</span><span class="special"><</span><span class="keyword">char</span><span class="special">[],</span> <span class="identifier">size</span><span class="special">></span> <span class="identifier">buffer</span><span class="special">(</span><span class="keyword">new</span> <span class="keyword">char</span><span class="special">[</span><span class="identifier">size</span><span class="special">]);</span> <span class="comment">//allocate a buffer for the import</span>
|
||
<span class="identifier">alias</span> <span class="special">&</span> <span class="identifier">inst</span> <span class="special">=</span> <span class="special">*</span><span class="keyword">reinterpret_cast</span><span class="special"><</span><span class="identifier">alias</span><span class="special">*>(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">get</span><span class="special">());</span> <span class="comment">//cast it to our alias type.</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
Now, we have the memory size and a reference with our alias type. In order
|
||
to use it, we need to register the type as an alias. That will allow the
|
||
smart library to resolve the type name.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">lib</span><span class="special">.</span><span class="identifier">add_type_alias</span><span class="special">(</span><span class="string">"space::my_plugin"</span><span class="special">);</span> <span class="comment">//add an alias, so i can import a class that is not declared here</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
In order to use the class, we of course need to initialize it, i.e. call
|
||
the constructor. The Itanium ABI may also implement an allocating constructor.
|
||
That is why a constructor may have two functions; since we already have allocated
|
||
the memory we use the standard constructor version, of the constructor from
|
||
string. So we select the constructor by passing the signature.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">ctor</span> <span class="special">=</span> <span class="identifier">lib</span><span class="special">.</span><span class="identifier">get_constructor</span><span class="special"><</span><span class="identifier">alias</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="comment">//get the constructor</span>
|
||
<span class="identifier">ctor</span><span class="special">.</span><span class="identifier">call_standard</span><span class="special">(&</span><span class="identifier">inst</span><span class="special">,</span> <span class="string">"MyName"</span><span class="special">);</span> <span class="comment">//call the non-allocating constructor. The allocating-constructor is a non-portable feature</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
So since the class is now initialized, we can call the name method. If the
|
||
function is const and/or volatile the type parameter passed as type must
|
||
have the same qualifiers.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">name_f</span> <span class="special">=</span> <span class="identifier">lib</span><span class="special">.</span><span class="identifier">get_mem_fn</span><span class="special"><</span><span class="keyword">const</span> <span class="identifier">alias</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="string">"name"</span><span class="special">);//</span><span class="identifier">import</span> <span class="identifier">the</span> <span class="identifier">name</span> <span class="identifier">function</span>
|
||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Name Call: "</span> <span class="special"><<</span> <span class="special">(</span><span class="identifier">inst</span><span class="special">.*</span><span class="identifier">name_f</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>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
Overloaded functions can only be imported separately.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="comment">//import both calculate functions</span>
|
||
<span class="keyword">auto</span> <span class="identifier">calc_f</span> <span class="special">=</span> <span class="identifier">lib</span><span class="special">.</span><span class="identifier">get_mem_fn</span><span class="special"><</span><span class="identifier">alias</span><span class="special">,</span> <span class="keyword">float</span><span class="special">(</span><span class="keyword">float</span><span class="special">,</span> <span class="keyword">float</span><span class="special">)>(</span><span class="string">"calculate"</span><span class="special">);</span>
|
||
<span class="keyword">auto</span> <span class="identifier">calc_i</span> <span class="special">=</span> <span class="identifier">lib</span><span class="special">.</span><span class="identifier">get_mem_fn</span><span class="special"><</span><span class="identifier">alias</span><span class="special">,</span> <span class="keyword">int</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)></span> <span class="special">(</span><span class="string">"calculate"</span><span class="special">);</span>
|
||
|
||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"calc(float): "</span> <span class="special"><<</span> <span class="special">(</span><span class="identifier">inst</span><span class="special">.*</span><span class="identifier">calc_f</span><span class="special">)(</span><span class="number">5.</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>
|
||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"calc(int) : "</span> <span class="special"><<</span> <span class="special">(</span><span class="identifier">inst</span><span class="special">.*</span><span class="identifier">calc_f</span><span class="special">)(</span><span class="number">5</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>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
Import of static variable is done like with plain variable.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">auto</span> <span class="special">&</span> <span class="identifier">var</span> <span class="special">=</span> <span class="identifier">lib</span><span class="special">.</span><span class="identifier">get_variable</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="string">"space::my_plugin::value"</span><span class="special">);</span>
|
||
<span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"value "</span> <span class="special"><<</span> <span class="identifier">var</span> <span class="special"><<</span> <span class="identifier">endl</span><span class="special">;</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
Since we are finished, we call the destructor of the class.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"> <span class="keyword">auto</span> <span class="identifier">dtor</span> <span class="special">=</span> <span class="identifier">lib</span><span class="special">.</span><span class="identifier">get_destructor</span><span class="special"><</span><span class="identifier">alias</span><span class="special">>();</span> <span class="comment">//get the destructor</span>
|
||
<span class="identifier">dtor</span><span class="special">.</span><span class="identifier">call_standard</span><span class="special">(&</span><span class="identifier">inst</span><span class="special">);</span>
|
||
<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>
|
||
<span class="special">}</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
<a class="link" href="mangled_import.html" title="Mangled Import">Back to the Top</a>
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_dll.mangled_import.class_import"></a><a class="link" href="mangled_import.html#boost_dll.mangled_import.class_import" title="Class Import">Class Import</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
Now it is demonstrated, how mangled and methods may be imported. This is
|
||
however a rather versatile way, so an easier interface is provided, which
|
||
also allows access to the type_info of an object.
|
||
</p>
|
||
<p>
|
||
We will take the same class and import the same methods, but do it with the
|
||
import features.
|
||
</p>
|
||
<p>
|
||
We put the library into a shared_pointer, because every import will hold
|
||
such a pointer to it. That is, we do not want to copy it.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<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">smart_library</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<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_mangled</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<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_class</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
|
||
|
||
|
||
<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>
|
||
|
||
<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>
|
||
<span class="identifier">smart_library</span> <span class="identifier">lib</span><span class="special">(</span><span class="identifier">lib_path</span><span class="special">);//</span> <span class="identifier">smart</span> <span class="identifier">library</span> <span class="identifier">instance</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
Similar to the previous example, we need the size of the class.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">size_f</span> <span class="special">=</span> <span class="identifier">import_mangled</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">()>(</span><span class="string">"space::my_plugin::size"</span><span class="special">);</span> <span class="comment">//get the size function</span>
|
||
|
||
<span class="keyword">auto</span> <span class="identifier">size</span> <span class="special">=</span> <span class="special">(*</span><span class="identifier">size_f</span><span class="special">)();</span> <span class="comment">// get the size of the class</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
On a side note, we can also import variable easily with that function.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">import_mangled</span><span class="special"><</span><span class="keyword">int</span><span class="special">>(</span><span class="identifier">lib</span><span class="special">,</span> <span class="string">"space::my_plugin::value"</span><span class="special">);</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
We do the forward declaration on the first call, and invoke the constructor
|
||
directly. This is quite simple and allows to invoke the constructor directly.
|
||
The destructor will be invoked automatically.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">cl</span> <span class="special">=</span> <span class="identifier">import_class</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">alias</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">lib</span><span class="special">,</span> <span class="string">"space::my_plugin::some_class"</span><span class="special">,</span> <span class="identifier">size</span><span class="special">,</span> <span class="string">"MyName"</span><span class="special">);</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
Invoking a function will still require to import it first.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">name</span> <span class="special">=</span> <span class="identifier">import_mangled</span><span class="special"><</span><span class="keyword">const</span> <span class="identifier">alias</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">lib</span><span class="special">,</span> <span class="string">"name"</span><span class="special">);</span>
|
||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Name: "</span> <span class="special"><<</span> <span class="special">(</span><span class="identifier">cl</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>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
For overloaded functions, we can import them as groups, which will give us
|
||
an object containing the overloads.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">calc</span> <span class="special">=</span> <span class="identifier">import_mangled</span><span class="special"><</span><span class="identifier">alias</span><span class="special">,</span> <span class="keyword">float</span><span class="special">(</span><span class="keyword">float</span><span class="special">,</span> <span class="keyword">float</span><span class="special">),</span> <span class="keyword">int</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)>(</span><span class="identifier">lib</span><span class="special">,</span> <span class="string">"calculate"</span><span class="special">);</span>
|
||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Calc(float): "</span> <span class="special">(</span><span class="identifier">cl</span><span class="special">->*</span><span class="identifier">calc</span><span class="special">)(</span><span class="number">5.f</span><span class="special">,</span> <span class="number">2.f</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>
|
||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Calc(int): "</span> <span class="special">(</span><span class="identifier">cl</span><span class="special">->*</span><span class="identifier">calc</span><span class="special">)(</span><span class="number">5</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>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
Additionally, we can access the typeinfo like this.
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">type_info</span> <span class="special">&</span><span class="identifier">ti</span> <span class="special">=</span> <span class="identifier">cl</span><span class="special">.</span><span class="identifier">get_type_info</span><span class="special">();</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
<a class="link" href="mangled_import.html" title="Mangled Import">Back to the Top</a>
|
||
</p>
|
||
</div>
|
||
<div class="section">
|
||
<div class="titlepage"><div><div><h3 class="title">
|
||
<a name="boost_dll.mangled_import.overloading_qualifiers"></a><a class="link" href="mangled_import.html#boost_dll.mangled_import.overloading_qualifiers" title="Overloading qualifiers">Overloading
|
||
qualifiers</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
Not handled in the example was the question, of how it is handled if the
|
||
qualification differs for an overloaded function. This can be done, by passing
|
||
the class again with another qualification - a function signature will always
|
||
pick the last one provided.
|
||
</p>
|
||
<p>
|
||
If we have this in our plugin:
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">plugin</span>
|
||
<span class="special">{</span>
|
||
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">);</span>
|
||
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">double</span><span class="special">);</span>
|
||
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
|
||
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
|
||
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">()</span> <span class="keyword">volatile</span><span class="special">;</span>
|
||
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span> <span class="keyword">volatile</span><span class="special">;</span>
|
||
<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">double</span><span class="special">);</span> <span class="keyword">const</span> <span class="keyword">volatile</span><span class="special">;</span>
|
||
<span class="special">};</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
<p>
|
||
we can import them all at once, with the following command:
|
||
</p>
|
||
<p>
|
||
</p>
|
||
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">f</span> <span class="special">=</span> <span class="identifier">import_class</span><span class="special"><</span>
|
||
<span class="identifier">alias</span><span class="special">,</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">),</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">double</span><span class="special">),</span> <span class="comment">//not qualified</span>
|
||
<span class="keyword">const</span> <span class="identifier">alias</span><span class="special">,</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">),</span> <span class="identifier">f</span><span class="special">(),</span> <span class="comment">//const</span>
|
||
<span class="keyword">volatile</span> <span class="identifier">alias</span><span class="special">,</span> <span class="identifier">f</span><span class="special">(),</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">int</span><span class="special">),</span> <span class="comment">//volatile</span>
|
||
<span class="keyword">const</span> <span class="keyword">volatile</span> <span class="identifier">alias</span><span class="special">,</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">double</span><span class="special">)//</span><span class="keyword">const</span> <span class="keyword">volatile</span>
|
||
<span class="special">>(</span><span class="identifier">lib</span><span class="special">,</span> <span class="string">"f"</span><span class="special">);</span>
|
||
</pre>
|
||
<p>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||
<td align="left"></td>
|
||
<td align="right"><div class="copyright-footer">Copyright © 2014 Renato Tegon Forti, Antony Polukhin<br>Copyright © 2015 Antony Polukhin<br>Copyright © 2016 Antony Polukhin, Klemens Morgenstern<br>Copyright © 2017-2021 Antony Polukhin<p>
|
||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||
</p>
|
||
</div></td>
|
||
</tr></table>
|
||
<hr>
|
||
<div class="spirit-nav">
|
||
<a accesskey="p" href="tutorial.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="missuses.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
|
||
</div>
|
||
</body>
|
||
</html>
|