]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [/ |
2 | Copyright 2014 Renato Tegon Forti, Antony Polukhin | |
3 | Distributed under the Boost Software License, Version 1.0. | |
4 | (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | /] | |
6 | ||
7 | [section Design Rationale] | |
8 | ||
9 | [section ABI portability across compilers] | |
10 | ||
11 | During discussion of the library a lot of questions were about ABI stability and should the library | |
12 | take care about it. It was decided that making ABI stable could be a useful feature, but it will | |
13 | add a lot of overhead and make the library usage less simple. For those who do not require ABI | |
14 | stability across compilers such feature will be an overkill. | |
15 | ||
16 | It was decided to make this library more simple and low level, so that it could be used to make ABI | |
17 | stable plugins system for users that require it still not adding overhead for other users. | |
18 | ||
19 | [endsect] | |
20 | ||
21 | ||
22 | [section User's plugin API] | |
23 | ||
24 | There are some open C++ plugin systems. Most of them force user to have some predefined API. The | |
25 | problem is that all of those API differ. | |
26 | ||
27 | To be more usable Boost.DLL does not force API. It's up to user to design suitable API. | |
28 | ||
29 | [endsect] | |
30 | ||
31 | [section Performance and memory allocations] | |
32 | ||
33 | Some methods of the library use `boost::filesystem::path` or return `std::vector<std::string>`. This | |
34 | may look non optimal at first, but there is a reason to do so. | |
35 | ||
36 | `boost::filesystem::path` allows to transparently use Unicode strings with non-Unicode ones. Using it | |
37 | provides a more user-friendly interface for the library while the performance overhead is not noticeable | |
38 | because of a slow file system operations that occur in `boost::filesystem::path` accepting methods. | |
39 | ||
40 | `std::vector<std::string>` variables are returned by the `library_info` methods. Querying a library is a slow | |
41 | procedure anyway: it randomly reads parts of file from disc and executes algorithms that sometimes | |
42 | have linear complexity from sections or exported symbols count. Returning `std::vector<std::string>` | |
43 | simplifies implementation and does not require from user to keep an instance of `library_info` after | |
44 | query. Having not a very noticeable performance overhead in rarely called methods seems reasonable. | |
45 | ||
46 | Other methods are assumed to be hot paths and optimized as much as possible. | |
47 | ||
48 | [endsect] | |
49 | ||
50 | [section Self loading] | |
51 | ||
52 | There is a good big reason to make self loading via `shared_library(program_location())` instead of | |
53 | having some `shared_library::load_self()` member method. That reason is the requirement to have an ability to call | |
54 | `shared_library(this_line_location())` from any place, even from the main binary. We need that to link plugins | |
55 | into the binary and to create a transparent reference counting mechanism. | |
56 | ||
57 | Making multiple interfaces that do exactly the same things looks unreasonable to me, that's why | |
58 | `shared_library(program_location())` and `shared_library(this_line_location())` are used without | |
59 | `shared_library::load_self()`. | |
60 | ||
61 | [endsect] | |
62 | ||
63 | [section Aliases vs Mangling] | |
64 | ||
65 | Mangling depends on source code, for example `"boost::foo"` could be `foo` function or `foo` variable. | |
66 | Depending on that knowledge it must be mangled in different ways. More problems arise if `foo` is an | |
67 | overloaded function that accepts parameters: `"boost::foo(variant<int, short>)"`. In that case full | |
68 | name of parameter must be specified, which could be `boost::variant<int, short>` or `variant<int, short, void_, void_>` | |
69 | ... | |
70 | ||
71 | There was an idea to allow user to forward declare function and generate mangled name from it: | |
72 | ||
73 | ``` | |
74 | namespace boost { void foo(variant<int, short>); } | |
75 | ||
76 | std::string mangled_name = boost::dll::magic_mangle(boost::foo); | |
77 | ``` | |
78 | ||
79 | But that idea has epic failed because of linker problems and no reliable way to get mangled symbol name | |
80 | from compiler internals at compile time. | |
81 | ||
82 | That's why aliases were considered a lesser evil: | |
83 | ||
84 | ``` | |
85 | BOOST_DLL_ALIAS(boost::foo, foo_variant) // in plugin | |
86 | "foo_variant" // in plugin importer | |
87 | ``` | |
88 | ||
89 | [endsect] | |
90 | ||
91 | ||
92 | [endsect] | |
93 |