]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Copyright 2014 Renato Tegon Forti, Antony Polukhin. |
b32b8144 | 2 | // Copyright 2015-2017 Antony Polukhin. |
7c673cae FG |
3 | // |
4 | // Distributed under the Boost Software License, Version 1.0. | |
5 | // (See accompanying file LICENSE_1_0.txt | |
6 | // or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | //[plugcpp_my_plugin_refcounting_api | |
9 | #include "../tutorial_common/my_plugin_api.hpp" | |
10 | #include <boost/filesystem/path.hpp> | |
11 | ||
12 | class my_refcounting_api: public my_plugin_api { | |
13 | public: | |
14 | // Returns path to shared object that holds a plugin. | |
15 | // Must be instantiated in plugin. | |
16 | virtual boost::filesystem::path location() const = 0; | |
17 | }; | |
18 | //] | |
19 | ||
20 | ||
21 | //[plugcpp_library_holding_deleter_api_bind | |
22 | #include <boost/shared_ptr.hpp> | |
23 | #include <boost/make_shared.hpp> | |
24 | #include <boost/dll/shared_library.hpp> | |
25 | ||
26 | struct library_holding_deleter { | |
27 | boost::shared_ptr<boost::dll::shared_library> lib_; | |
28 | ||
29 | void operator()(my_refcounting_api* p) const { | |
30 | delete p; | |
31 | } | |
32 | }; | |
33 | ||
34 | inline boost::shared_ptr<my_refcounting_api> bind(my_refcounting_api* plugin) { | |
35 | // getting location of the shared library that holds the plugin | |
36 | boost::filesystem::path location = plugin->location(); | |
37 | ||
38 | // `make_shared` is an efficient way to create a shared pointer | |
39 | boost::shared_ptr<boost::dll::shared_library> lib | |
40 | = boost::make_shared<boost::dll::shared_library>(location); | |
41 | ||
42 | library_holding_deleter deleter; | |
43 | deleter.lib_ = lib; | |
44 | ||
45 | return boost::shared_ptr<my_refcounting_api>( | |
46 | plugin, deleter | |
47 | ); | |
48 | } | |
49 | //] | |
50 | ||
51 | //[plugcpp_get_plugin_refcounting | |
52 | #include <boost/dll/import.hpp> | |
53 | #include <boost/function.hpp> | |
54 | inline boost::shared_ptr<my_refcounting_api> get_plugin( | |
55 | boost::filesystem::path path, const char* func_name) | |
56 | { | |
57 | typedef my_refcounting_api*(func_t)(); | |
58 | boost::function<func_t> creator = boost::dll::import_alias<func_t>( | |
59 | path, | |
60 | func_name, | |
61 | boost::dll::load_mode::append_decorations // will be ignored for executable | |
62 | ); | |
63 | ||
64 | // `plugin` does not hold a reference to shared library. If `creator` will go out of scope, | |
65 | // then `plugin` can not be used. | |
66 | my_refcounting_api* plugin = creator(); | |
67 | ||
68 | // Returned variable holds a reference to | |
69 | // shared_library and it is safe to use it. | |
70 | return bind( plugin ); | |
71 | ||
72 | // `creator` goes out of scope here and will be destroyed. | |
73 | } | |
74 | ||
75 | //] | |
76 | ||
77 |