95 lines
3.8 KiB
Plaintext
95 lines
3.8 KiB
Plaintext
[/
|
|
Copyright 2014 Renato Tegon Forti, Antony Polukhin
|
|
Copyright 2015-2019 Antony Polukhin
|
|
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)
|
|
/]
|
|
|
|
[section Design Rationale]
|
|
|
|
[section ABI portability across compilers]
|
|
|
|
During discussion of the library a lot of questions were about ABI stability and should the library
|
|
take care about it. It was decided that making ABI stable could be a useful feature, but it will
|
|
add a lot of overhead and make the library usage less simple. For those who do not require ABI
|
|
stability across compilers such feature will be an overkill.
|
|
|
|
It was decided to make this library more simple and low level, so that it could be used to make ABI
|
|
stable plugins system for users that require it still not adding overhead for other users.
|
|
|
|
[endsect]
|
|
|
|
|
|
[section User's plugin API]
|
|
|
|
There are some open C++ plugin systems. Most of them force user to have some predefined API. The
|
|
problem is that all of those API differ.
|
|
|
|
To be more usable Boost.DLL does not force API. It's up to user to design suitable API.
|
|
|
|
[endsect]
|
|
|
|
[section Performance and memory allocations]
|
|
|
|
Some methods of the library use `boost::filesystem::path` or return `std::vector<std::string>`. This
|
|
may look non optimal at first, but there is a reason to do so.
|
|
|
|
`boost::filesystem::path` allows to transparently use Unicode strings with non-Unicode ones. Using it
|
|
provides a more user-friendly interface for the library while the performance overhead is not noticeable
|
|
because of a slow file system operations that occur in `boost::filesystem::path` accepting methods.
|
|
|
|
`std::vector<std::string>` variables are returned by the `library_info` methods. Querying a library is a slow
|
|
procedure anyway: it randomly reads parts of file from disc and executes algorithms that sometimes
|
|
have linear complexity from sections or exported symbols count. Returning `std::vector<std::string>`
|
|
simplifies implementation and does not require from user to keep an instance of `library_info` after
|
|
query. Having not a very noticeable performance overhead in rarely called methods seems reasonable.
|
|
|
|
Other methods are assumed to be hot paths and optimized as much as possible.
|
|
|
|
[endsect]
|
|
|
|
[section Self loading]
|
|
|
|
There is a good big reason to make self loading via `shared_library(program_location())` instead of
|
|
having some `shared_library::load_self()` member method. That reason is the requirement to have an ability to call
|
|
`shared_library(this_line_location())` from any place, even from the main binary. We need that to link plugins
|
|
into the binary and to create a transparent reference counting mechanism.
|
|
|
|
Making multiple interfaces that do exactly the same things looks unreasonable to me, that's why
|
|
`shared_library(program_location())` and `shared_library(this_line_location())` are used without
|
|
`shared_library::load_self()`.
|
|
|
|
[endsect]
|
|
|
|
[section Aliases vs Mangling]
|
|
|
|
Mangling depends on source code, for example `"boost::foo"` could be `foo` function or `foo` variable.
|
|
Depending on that knowledge it must be mangled in different ways. More problems arise if `foo` is an
|
|
overloaded function that accepts parameters: `"boost::foo(variant<int, short>)"`. In that case full
|
|
name of parameter must be specified, which could be `boost::variant<int, short>` or `variant<int, short, void_, void_>`
|
|
...
|
|
|
|
There was an idea to allow user to forward declare function and generate mangled name from it:
|
|
|
|
```
|
|
namespace boost { void foo(variant<int, short>); }
|
|
|
|
std::string mangled_name = boost::dll::magic_mangle(boost::foo);
|
|
```
|
|
|
|
But that idea has epic failed because of linker problems and no reliable way to get mangled symbol name
|
|
from compiler internals at compile time.
|
|
|
|
That's why aliases were considered a lesser evil:
|
|
|
|
```
|
|
BOOST_DLL_ALIAS(boost::foo, foo_variant) // in plugin
|
|
"foo_variant" // in plugin importer
|
|
```
|
|
|
|
[endsect]
|
|
|
|
|
|
[endsect]
|
|
|