boost/python/extract.hpp

はじめに

一般的な Python オブジェクトから C++ オブジェクトの値を抽出する機構をエクスポートする。extract<>object を特定の ObjectWrapper に「ダウンキャスト」するのにも使用できるということに注意していただきたい。可変の Python 型について同じ型で呼び出すと(例えば list([1,2]))一般的にはその引数のコピーが作成されるため、これが元のオブジェクトにおける ObjectWrapper インターフェイスにアクセスする唯一の方法となる可能性がある。

クラス

extract クラステンプレート

template<class T>
struct extract

extract を使用すると object のインスタンスから任意の C++ 型の値を抽出できる。2 つの使用方法をサポートする:

  1. extract<T>(o) は、T へ暗黙に変換可能な一時オブジェクトである(オブジェクトの関数呼び出し演算子による明示的な変換も可能である)。しかしながら o から型 T のオブジェクトへの変換が利用できない場合は、Python の TypeError 例外を送出する

  2. extract<T> x(o) は、例外を投げることなく変換が可能か問い合わせる check メンバ関数を持つ抽出子を構築する。

extract クラステンプレートの概要

namespace boost { namespace python
{
  template <class T>
  struct extract
  {
      typedef unspecified result_type;

      extract(PyObject*);
      extract(object const&);

      result_type operator()() const;
      operator result_type() const;

      bool check() const;
  };
}}

extract クラステンプレートのコンストラクタおよびデストラクタ

extract(PyObject *p)
extract(object const&)
要件

第 1 形式では p は非 null でなければならない。

効果

コンストラクタの引数が管理する Python オブジェクトへのポインタを格納する。特にオブジェクトの参照カウントは増加しない。抽出子の変換関数が呼び出される前にオブジェクトが破壊されないようにするのはユーザの責任である。

extract クラステンプレートのオブザーバ関数

result_type operator()() const
operator result_type() const
効果

格納したポインタを result_type へ変換する。これは TT const& である。

戻り値

格納したポインタが参照するものに対応する result_type のオブジェクト。

例外

error_already_set -- そのような変換が不可能な場合(TypeError を設定する)。実際に使用している変換器が未規定の他の例外を投げる可能性がある。

bool check() const
事後条件

なし。特に戻り値が true であっても operator result_typeoperator() が例外を投げないとは限らないことに注意していただきたい。

戻り値

格納したポインタから T への変換が不可能な場合のみ false

#include <cstdio>
using namespace boost::python;
int Print(str s)
{
   // Python の文字列オブジェクトから C の文字列を抽出する
   char const* c_str = extract<char const*>(s);

   // printf で印字する
   std::printf("%s\n", c_str);

   // Python の文字列の長さを取得し、整数へ変換する
   return extract<int>(s.attr("__len__")())
}

以下は extract<>class_<> を使用して、ラップした C++ クラスのインスタンスを作成しアクセスする例である。

struct X
{
   X(int x) : v(x) {}
   int value() { return v; }
 private:
   int v;
};

BOOST_PYTHON_MODULE(extract_ext)
{
    object x_class(
       class_<X>("X", init<int>())
          .def("value", &X::value))
          ;

    // Python のインターフェイスを介して X のオブジェクトをインスタンス化する。
    // 寿命は以降、x_objが管理する。
    object x_obj = x_class(3);

    // Python のオブジェクトを使用せずに C++ オブジェクトへの参照を取得する
    X& x = extract<X&>(x_obj);
    assert(x.value() == 3);
}