[/
    Copyright 2016 Klemens D. Morgenstern
    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)
/]

[template mangled_ref[path] '''<ulink url="https://github.com/apolukhin/Boost.DLL/blob/develop/example/'''[path]'''">example/'''[path]'''</ulink>''']

[def __to_top [link boost_dll.mangled_import Back to the Top]]

[section Mangled Import]

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.

\warning Experimental feature that relies on an incomplete implementation of platform specific C++
         mangling. In case of an issue provide a PR with a fix and tests to https://github.com/boostorg/dll

As a short example we can import the following functions quite easily:

```
//library.dll
namespace foo {
int    bar(int);
double bar(double);
}
``` 

And the import looks like this:

```
auto f1 = import_mangled<int(int)>("library.dll", "foo::bar");
auto f2 = import_mangled<double(double)>("library.dll", "foo::bar");
cout << f1(42)  << endl;
cout << f2(3.2) << endl;
```

[section Support & Requirements]

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. 

* Gcc 
* Clang
* MSVC 2015
* Intel C++

The Itanium API does not import the return type of functions, nor the type of global variables.

[endsect]

[section Mangled Import Example]

The core of the mangled import is the [classref smart_library] 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.

In order to import all the methods in the following library, we will use the [classref smart_library] .

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:

[import ../example/mangled/my_cpp_plugin.hpp]
[cppplug]

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 [classref smart_lib] provides as features.

[import ../example/mangled/smart_lib.cpp]

At first we setup the smart library. Mind that the alias class is needed to provide a type-alias for the my_plugin.
[smart_lib_setup]

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.

So we import it, call it and allocate memory.

[smart_lib_size]

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.

[smart_lib_type_alias]

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.

[smart_lib_ctor]

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.

[smart_lib_name]

Overloaded functions can only be imported separately.

[smart_lib_calculate]

Import of static variable is done like with plain variable.

[smart_lib_var]

Since we are finished, we call the destructor of the class. 

[smart_lib_dtor]

__to_top

[endsect]

[section Class Import]

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.

We will take the same class and import the same methods, but do it with the import features.

[import ../example/mangled/import_class.cpp]

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.

[import_class_setup]

Similar to the previous example, we need the size of the class.

[import_class_size]

On a side note, we can also import variable easily with that function.

[import_class_value]

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.

[import_class_ctor]

Invoking a function will still require to import it first.

[import_class_name]

For overloaded functions, we can import them as groups, which will give us an object containing the overloads.

[import_class_calc]

Additionally, we can access the typeinfo like this.

[import_class_typeinfo]

__to_top

[endsect]

[section Overloading qualifiers]

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.

If we have this in our plugin:
```
struct plugin
{
    void f(int);
    void f(double);
    void f(int) const;
    void f() const;
    void f() volatile;
    void f(int) volatile;
    void f(double); const volatile;
};
```

we can import them all at once, with the following command:

```
    auto f = import_class<
        alias, f(int), f(double), //not qualified
        const alias, f(int), f(), //const
        volatile alias, f(), f(int), //volatile
        const volatile alias, f(double)//const volatile
        >(lib, "f");

```

[endsect]
[endsect]


