12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- [/
- 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]
|