This issue describes possible features I'd like to add to boost.DLL.
Preface
I was recently working on a shared library import library, though with a few more features boost.DLL does not have. It is currently more a proof-of-concept, but I could certify (on windows with gcc 5.1 and MSVC) that these work. Since Clang uses the same ABI as Gcc, I am quite confident that this will work on most platforms.
Idea
The basic Idea is to implement loading of mangled names. This shall be done by reading the complete outline from the shared library and demangle each name. These demangled names will then be stored in a map with the mangled one.
That way we can easily match names for requested functions.
If this is added to boost.DLL, it would be an additional class, which shared a shared_lib.
The examples given below are overly simple on purpose. I don't have a detailed design for the library, but I will add it during development. This shall give a basic idea and start a discussion.
Mangled Functions and Variables
Loading a plain mangled name is quite easy, though I have to add, that it's also type-safe in MSVC, since this compiler also mangles the typename, whlie the Itanium ABI does not. I will later discuss how this could be added for GCC.
So now, compared to the plain boost.dll, a mangled name can be loaded rather easy:
var = dll::import_variable<int>("some_namespace::variable");
The check if the name is mangled is in itself trivial. Or for static functions:
plugin = dll::import_function<int(double)>("some_namespace::some_function");
Constructors/Destructors and Member functions
It is basicly as easy to get pointers to member-functions and constructors. Constructors and Member-functions behave in the same way, so once we have enough allocated memory, we can explicitly call the constructors.
Getting a Constructor:
plugin = dll::import_constructor<void(int, int)>("some_namespace::some_class");
Loading a member-function:
Getting a Constructor:
plugin = dll::import_constructor<double(int, int)>("some_namespace::some_class::method");
Safe Import
Now if we import a constructor, we can call him like a member-function, but we still do not know which size it has.
Hence we need a mechanism to import this safely. Additionally such a mechanism would also provide a safe import for all variables and functions, because we know their (return) types.
Variant 1 - Each export has a symbol
Now quite simple is the following solution: export a symbol for each variable, e.g.:
#define EXPORT_VARIABLE(Name) \
namespace boost { namespace dll_export { \
struct Name##Export { static size_t size() {return sizeof(Name);}; }}}
We could also export it's type this way. The problem is, that the outline looks aweful afterwards.
Variant 2 - Export Table
We declare a global variable, which holds all information. Out macro will declary a dummy, whoms constructor will pass information to a singleton. This singleton then is exported.
I didn't think this concept through, but I will give it some thought as soon as I am finished with the core.
Status
As mentioned in the beginning, I have a proof-of-concept implemenation and I am currently working on building a implementation which ties into boost.dll. This will be the major part, i.e. to develop a layer which allows the import of mangled functions. If that works, one of the concepts described above will come in place, and I will exploit the type system, to construct type safety while importing functions.