プラグインシステムを Boost.DLL で簡単に実装する紹介

# この記事の想定するユーザー

- C++ の基礎的な扱いには問題ない方
- Boost を利用できる環境を用意できる方
- ネイティブのバイナリーのプラグインシステムに興味がある方
    - 共有ライブラリー(.soや.dll)のOS毎のネイティブAPIの直叩きや、柵の強いフレームワークに頼った実装をしたくない方、クロスプラットフォームポータビリティーに興味がある方
    - 独自のプラグインシステムの実装に疲れた方

# 簡単なクラスレベルのプラグイン

簡単・ｗ・

## 用意するもの

1. plugin_type.hxx : この節で紹介するプラグインの基底型のソース。アプリとプラグインのそれぞれから include して使う。
2. plugin_a.cxx : plugin_type を基に実装される具体的なプラグインのソース。
3. app.cxx : プラグインを使いたいアプリのソース。

plugin_type.hxx:

```cpp
#pragma once

#include <string>

namespace usagi::example::boost_dll
{
  class plugin_type
  {
    public:
      virtual auto get_name() const -> std::string;
      virtual auto operator()( const int a, const int b ) const -> int;
      virtual ~plugin_type() { }
  };
}
```

plugin_a.cxx:

```cpp
#include "plugin_type.hxx"
#include <boost/config.hpp>

namespace usagi::example::boost_dll
{
  class plugin_a : public plugin_type
  {
    public:
      auto get_name() const -> std::string override { return "adder"; }
      auto operator()( const int a, const int b ) const -> int override { return a + b; };
  };
  
  extern "C" BOOST_SYMBOL_EXPORT plugin_a plugin;
  plugin_a plugin;
}
```

app.cxx:

```cpp
#include "plugin_type.hxx"
#include <boost/dll/import.hpp>
#include <iostream>

auto main() -> int
{
  using namespace std;
  using namespace usagi::example::boost_dll;
  // ↓ op は boost::shared_ptr< plugin_type > 型で与えられる。
  // （std::shared_ptr へ変換したい場合は参考†を参照。）
  auto op =
    boost::dll::import< plugin_type >
    // ↓ロードするプラグインのパス（実用の際は一般に決め打ちにしない事が多い）
    ( boost::filesystem::path( "plugin_a" )
    // ↓インポートする対象のプラグインでエクスポートされているシンボル
    , "plugin"
    // ↓これを付けておくと、 .so や .dll をパスに勝手に追加してくれて便利
    , boost::dll::load_mode::append_decorations
    );
  
  cout << op->get_name() << " " << (*op)( 1, 2 ) << endl;
}
```

# 応用: poker のプレイヤーAIをプラグイン化して遊べるようにしてみる例

↑と、いう記事だけ書いてもあまり面白みがないので、↓こんなのを[大晦日ハッカソン2016](https://atnd.org/events/83845#)で作ってみました。（できて、この記事を書いている現在、既に1月4日だけどねヽ(´ー｀)ノ）

- [GitHub - usagi/poker](https://github.com/usagi/poker) : 作者が自身のワークショップや勉強会向けとして開発するプラガブルなポーカーシステムです。

![image](https://qiita-image-store.s3.amazonaws.com/0/33891/f357f8e5-ebe9-2315-2709-704e37965385.png)

↑こんな感じでプレイヤーAIのプラグインをちょろりと書くと、↓こんな具合で楽しめます。

![image](https://qiita-image-store.s3.amazonaws.com/0/33891/20a12b7e-5254-8ded-0afb-d6eeb5e9c8d6.png)

## 宣伝：「わんくま札幌」はじまりますヽ(´ー｀)ノ

2017年より[わんくま同盟](http://www.wankuma.com/)の札幌支部として、[わんくま勉強会・札幌を年2回のペースで開催](http://www.wankuma.com/seminar/default.aspx)できる事になりました！2017年は3月4日にわんくま札幌#1、8月5日にわんくま札幌#2を開催します。30分、60分のセッション枠、LT枠、おやつなどなど準備して皆様のご参加＆登壇のお申込みを心よりお待ちしております。🍻🍶🍣

私の枠が発生したわんくま札幌回では、今回の記事で紹介した poker システムをベースにしたアルゴリズム脳汁体操系のワークショップを行おうかな、と思っています。その際はC++のネイティブ実装の他にも何かしらもう少しお手軽なスクリプト言語のバインディングなどにも対応し、C++入門ではなくアルゴリズム脳汁体操として多くの参加者に楽しんで頂ける内容になればと考えています。鉞とか闇がどうしたとか気にせずに、ぜひ「わんくま札幌」へ遊びにいらして下さい！

ちなみに、今年からしばらくは、この poker を機能拡張したり、リファクタリングしたり、そうした折毎に都度 C++ の実装例など技術的な部分の入門者向けの記事部分は Qiita へ投稿するつもりですので、こちらも引き続きよろしくお願いいたします。

# 参考

- [Chapter 10. Boost.DLL](http://www.boost.org/doc/libs/1_61_0/doc/html/boost_dll.html)
    - [Tutorial](http://www.boost.org/doc/libs/1_61_0/doc/html/boost_dll/tutorial.html)
- †[boost::shared_ptr から std::shared_ptr へ変換する簡単な方法](http://qiita.com/usagi/items/3563ddb01e4eb342485e)