Skip to content

Commit

Permalink
Fix "Factory method in plugin" example and modernize all the examples…
Browse files Browse the repository at this point in the history
… (#86)

Fixes #62
  • Loading branch information
apolukhin authored Dec 22, 2024
1 parent 96ee80d commit f71d8e7
Show file tree
Hide file tree
Showing 15 changed files with 42 additions and 48 deletions.
10 changes: 5 additions & 5 deletions doc/tutorial.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Now let's make a DLL/DSO library that will holds implementation of plugin interf
[import ../example/tutorial1/my_plugin_sum.cpp]
[plugcpp_my_plugin_sum]

Simple application that loads plugin using the [funcref boost::dll::import]
Simple application that loads plugin using the [funcref boost::dll::import_symbol]
and [enumref boost::dll::load_mode::type append_decorations]:

[import ../example/tutorial1/tutorial1.cpp]
Expand Down Expand Up @@ -312,7 +312,7 @@ __to_top

[section Advanced library reference counting]

As noted in documentation to the [funcref boost::dll::import]
As noted in documentation to the [funcref boost::dll::import_symbol]
variables and functions returned from those functions hold a reference to the shared library. However nested objects and
objects that are returned by `import*` functions do not hold a reference to the shared library. There's no way to solve
this issue on the Boost.DLL library level, but you can take care of this problem by your own. Here's an example how this
Expand All @@ -339,7 +339,7 @@ Now let's define the plugin:

This plugin does not differ much from our previous examples except the additional method that calls
[funcref boost::dll::this_line_location] and `create()` function that returns a simple pointer instead of
`boost::shared_ptr`.
`std::shared_ptr`.

Now lets make a function that binds a newly created instance of `my_refcounting_api` to a shared library:
[plugcpp_library_holding_deleter_api_bind]
Expand All @@ -348,7 +348,7 @@ In `bind` method we call `plugin->location()`. This call results in a call to
[funcref boost::dll::this_line_location] and returns the plugin location. Then a `shared_ptr` that holds a `shared_library`
is created using the `make_shared` call.

After that we construct a `boost::shared_ptr<my_refcounting_api>` with a `library_holding_deleter` that keeps an instance of the shared library.
After that we construct a `std::shared_ptr<my_refcounting_api>` with a `library_holding_deleter` that keeps an instance of the shared library.

[note Use `std::unique_ptr<my_refcounting_api>` instead of `my_refcounting_api*` in production code to avoid memory leaks when `plugin->location()`
throws or when some other class rises an exception.]
Expand Down Expand Up @@ -389,7 +389,7 @@ __to_top
[section Importing a C function from Windows dll]

This a trivial example, but it has one tricky place. When you are importing a C function by *it's name*
you must use [funcref boost::dll::import], not [funcref boost::dll::import_alias]:
you must use [funcref boost::dll::import_symbol], not [funcref boost::dll::import_alias]:

[import ../example/tutorial9/tutorial9.cpp]
[callplugcpp_tutorial9]
Expand Down
6 changes: 3 additions & 3 deletions example/tutorial1/my_plugin_sum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@

namespace my_namespace {

class my_plugin_sum : public my_plugin_api {
class my_plugin_sum final: public my_plugin_api {
public:
my_plugin_sum() {
std::cout << "Constructing my_plugin_sum" << std::endl;
}

std::string name() const {
std::string name() const override {
return "sum";
}

float calculate(float x, float y) {
float calculate(float x, float y) override {
return x + y;
}

Expand Down
3 changes: 1 addition & 2 deletions example/tutorial1/tutorial1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ namespace dll = boost::dll;
int main(int argc, char* argv[]) {
/*<-*/ b2_workarounds::argv_to_path_guard guard(argc, argv); /*->*/
boost::dll::fs::path lib_path(argv[1]); // argv[1] contains path to directory with our plugin library
boost::shared_ptr<my_plugin_api> plugin; // variable to hold a pointer to plugin variable
std::cout << "Loading the plugin" << std::endl;

plugin = dll::import_symbol<my_plugin_api>( // type of imported symbol is located between `<` and `>`
auto plugin = dll::import_symbol<my_plugin_api>( // type of imported symbol is located between `<` and `>`
lib_path / "my_plugin_sum", // path to the library and library name
"plugin", // name of the symbol to import
dll::load_mode::append_decorations // makes `libmy_plugin_sum.so` or `my_plugin_sum.dll` from `my_plugin_sum`
Expand Down
12 changes: 6 additions & 6 deletions example/tutorial2/my_plugin_aggregator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <iostream>
#include <boost/make_shared.hpp>
#include <memory>

// MinGW related workaround
#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
Expand All @@ -17,23 +17,23 @@

namespace my_namespace {

class my_plugin_aggregator : public my_plugin_api {
class my_plugin_aggregator final: public my_plugin_api {
float aggr_;
my_plugin_aggregator() : aggr_(0) {}

public:
std::string name() const {
std::string name() const override {
return "aggregator";
}

float calculate(float x, float y) {
float calculate(float x, float y) override {
aggr_ += x + y;
return aggr_;
}

// Factory method
static boost::shared_ptr<my_plugin_aggregator> create() {
return boost::shared_ptr<my_plugin_aggregator>(
static std::shared_ptr<my_plugin_api> create() {
return std::shared_ptr<my_plugin_aggregator>(
new my_plugin_aggregator()
);
}
Expand Down
5 changes: 2 additions & 3 deletions example/tutorial2/tutorial2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

//[callplugcpp_tutorial2
#include <boost/dll/import.hpp> // for import_alias
#include <boost/function.hpp>
#include <iostream>
#include "../tutorial_common/my_plugin_api.hpp"

Expand All @@ -20,14 +19,14 @@ int main(int argc, char* argv[]) {
boost::dll::fs::path shared_library_path(argv[1]); // argv[1] contains path to directory with our plugin library
shared_library_path /= "my_plugin_aggregator";

using pluginapi_create_t = boost::shared_ptr<my_plugin_api>();
using pluginapi_create_t = std::shared_ptr<my_plugin_api>();
auto creator = boost::dll::import_alias<pluginapi_create_t>( // type of imported symbol must be explicitly specified
shared_library_path, // path to library
"create_plugin", // symbol to import
dll::load_mode::append_decorations // do append extensions and prefixes
);

boost::shared_ptr<my_plugin_api> plugin = creator();
std::shared_ptr<my_plugin_api> plugin = creator();
std::cout << "plugin->calculate(1.5, 1.5) call: " << plugin->calculate(1.5, 1.5) << std::endl;
std::cout << "plugin->calculate(1.5, 1.5) second call: " << plugin->calculate(1.5, 1.5) << std::endl;
std::cout << "Plugin Name: " << plugin->name() << std::endl;
Expand Down
5 changes: 2 additions & 3 deletions example/tutorial3/tutorial3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
#include "../b2_workarounds.hpp"
//[callplugcpp_tutorial3
#include <boost/dll/import.hpp> // for import_alias
#include <boost/make_shared.hpp>
#include <boost/function.hpp>
#include <iostream>
#include <memory>
#include "../tutorial_common/my_plugin_api.hpp"

namespace dll = boost::dll;
Expand All @@ -27,7 +26,7 @@ std::size_t search_for_symbols(const std::vector<boost::dll::fs::path>& plugins)
}

// library has symbol, importing...
using pluginapi_create_t = boost::shared_ptr<my_plugin_api>();
using pluginapi_create_t = std::shared_ptr<my_plugin_api>();
auto creator = dll::import_alias<pluginapi_create_t>(
std::move(lib), "create_plugin"
);
Expand Down
4 changes: 2 additions & 2 deletions example/tutorial4/load_self.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@
#include <boost/dll/shared_library.hpp> // for shared_library
#include <boost/dll/runtime_symbol_info.hpp> // for program_location()
#include "static_plugin.hpp" // without this headers some compilers may optimize out the `create_plugin` symbol
#include <boost/function.hpp>
#include <iostream>
#include <memory>

namespace dll = boost::dll;

int main() {
dll::shared_library self(dll::program_location());

std::cout << "Call function" << std::endl;
auto creator = self.get_alias<boost::shared_ptr<my_plugin_api>()>("create_plugin");
auto creator = self.get_alias<std::shared_ptr<my_plugin_api>()>("create_plugin");

std::cout << "Computed Value: " << creator()->calculate(2, 2) << std::endl;
//<-
Expand Down
12 changes: 6 additions & 6 deletions example/tutorial4/static_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@
//[plugcpp_my_plugin_staic_impl
#include "static_plugin.hpp" // this is essential, BOOST_SYMBOL_ALIAS must be seen in this file

#include <boost/make_shared.hpp>
#include <iostream>
#include <memory>

namespace my_namespace {

class my_plugin_static : public my_plugin_api {
class my_plugin_static final : public my_plugin_api {
public:
my_plugin_static() {
std::cout << "Constructing my_plugin_static" << std::endl;
}

std::string name() const {
std::string name() const override {
return "static";
}

float calculate(float x, float y) {
float calculate(float x, float y) override {
return x - y;
}

Expand All @@ -32,8 +32,8 @@ class my_plugin_static : public my_plugin_api {
}
};

boost::shared_ptr<my_plugin_api> create_plugin() {
return boost::make_shared<my_plugin_static>();
std::shared_ptr<my_plugin_api> create_plugin() {
return std::make_shared<my_plugin_static>();
}

} // namespace my_namespace
Expand Down
4 changes: 2 additions & 2 deletions example/tutorial4/static_plugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@

//[plugcpp_my_plugin_static
#include <boost/dll/alias.hpp> // for BOOST_DLL_ALIAS
#include <boost/shared_ptr.hpp>
#include <memory>
#include "../tutorial_common/my_plugin_api.hpp"

namespace my_namespace {
boost::shared_ptr<my_plugin_api> create_plugin(); // Forward declaration
std::shared_ptr<my_plugin_api> create_plugin(); // Forward declaration
} // namespace my_namespace

BOOST_DLL_ALIAS(
Expand Down
2 changes: 1 addition & 1 deletion example/tutorial5/load_all.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ void plugins_collector::load_all() {
void plugins_collector::insert_plugin(dll::shared_library&& lib) {
std::string plugin_name;
if (lib.has("create_plugin")) {
plugin_name = lib.get_alias<boost::shared_ptr<my_plugin_api>()>("create_plugin")()->name();
plugin_name = lib.get_alias<std::shared_ptr<my_plugin_api>()>("create_plugin")()->name();
} else if (lib.has("plugin")) {
plugin_name = lib.get<my_plugin_api>("plugin").name();
} else {
Expand Down
15 changes: 6 additions & 9 deletions example/tutorial8/refcounting_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,39 +19,36 @@ class my_refcounting_api: public my_plugin_api {


//[plugcpp_library_holding_deleter_api_bind
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <memory>
#include <boost/dll/shared_library.hpp>

struct library_holding_deleter {
boost::shared_ptr<boost::dll::shared_library> lib_;
std::shared_ptr<boost::dll::shared_library> lib_;

void operator()(my_refcounting_api* p) const {
delete p;
}
};

inline boost::shared_ptr<my_refcounting_api> bind(my_refcounting_api* plugin) {
inline std::shared_ptr<my_refcounting_api> bind(my_refcounting_api* plugin) {
// getting location of the shared library that holds the plugin
boost::dll::fs::path location = plugin->location();

// `make_shared` is an efficient way to create a shared pointer
boost::shared_ptr<boost::dll::shared_library> lib
= boost::make_shared<boost::dll::shared_library>(location);
auto lib = std::make_shared<boost::dll::shared_library>(location);

library_holding_deleter deleter;
deleter.lib_ = lib;

return boost::shared_ptr<my_refcounting_api>(
return std::shared_ptr<my_refcounting_api>(
plugin, deleter
);
}
//]

//[plugcpp_get_plugin_refcounting
#include <boost/dll/import.hpp>
#include <boost/function.hpp>
inline boost::shared_ptr<my_refcounting_api> get_plugin(
inline std::shared_ptr<my_refcounting_api> get_plugin(
boost::dll::fs::path path, const char* func_name)
{
using func_t = my_refcounting_api*();
Expand Down
6 changes: 3 additions & 3 deletions example/tutorial8/refcounting_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@

namespace my_namespace {

class my_plugin_refcounting : public my_refcounting_api {
class my_plugin_refcounting final: public my_refcounting_api {
public:
// Must be instantiated in plugin
boost::dll::fs::path location() const {
return boost::dll::this_line_location(); // location of this plugin
}

std::string name() const {
std::string name() const override {
return "refcounting";
}

// ...
//<-
// This block is invisible for Quickbook documentation
float calculate(float /*x*/, float /*y*/) {
float calculate(float /*x*/, float /*y*/) override {
return 0;
}
//->
Expand Down
2 changes: 1 addition & 1 deletion example/tutorial8/tutorial8.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

int main(int argc, char* argv[]) {
/*<-*/ b2_workarounds::argv_to_path_guard guard(argc, argv); /*->*/
boost::shared_ptr<my_refcounting_api> plugin = get_plugin(
std::shared_ptr<my_refcounting_api> plugin = get_plugin(
boost::dll::fs::path(argv[1]) / "refcounting_plugin",
"create_refc_plugin"
);
Expand Down
2 changes: 1 addition & 1 deletion example/tutorial8/tutorial8_static.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "refcounting_plugin.hpp"

int main() {
boost::shared_ptr<my_refcounting_api> plugin = get_plugin(
std::shared_ptr<my_refcounting_api> plugin = get_plugin(
boost::dll::program_location(),
"create_refc_plugin"
);
Expand Down
2 changes: 1 addition & 1 deletion example/tutorial_common/my_plugin_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class BOOST_SYMBOL_VISIBLE my_plugin_api {
virtual std::string name() const = 0;
virtual float calculate(float x, float y) = 0;

virtual ~my_plugin_api() {}
virtual ~my_plugin_api() = default;
};
//]

Expand Down

0 comments on commit f71d8e7

Please sign in to comment.