2016-07-06 10 views
2

C++コードをPythonに公開する場所によっては、PyObject*を使用する必要があります。 boost::python::class_オブジェクトのインスタンスがある場合は、ptr()を呼び出すことができます。しかし、もし私がちょうどそのタイプを持っていたら?Boost.Pythonタイプからハンドルを作成する

基本的には、タイプリストboost::python::bases<A, B, C>が与えられているので、PyErr_NewExceptionWithDoc()のようなものに渡すことができるインスタンスのboost::python::tupleに変換します。これは可能ですか?

+0

これが可能だったとしても、Pythonの例外タイプとBoost.Pythonの 'class_'の両方から継承するPython型を作成することは不可能です。だから私はこれが実用性よりも好奇心だと思う。 – Barry

答えて

1

C++タイプTを指定すると、boost::python::type_idオブジェクトを作成し、Boost.Pythonレジストリに登録情報を問い合わせることができます。エントリがレジストリに発見された場合には、1型T用に作成されたPythonクラスへのハンドルを取得するためにそれを使用することができます:ここでは

/// @brief Get the class object for a wrapped type that has been exposed 
///  through Boost.Python. 
template <typename T> 
boost::python::object get_instance_class() 
{ 
    // Query into the registry for type T. 
    namespace python = boost::python; 
    python::type_info type = python::type_id<T>(); 
    const python::converter::registration* registration = 
    python::converter::registry::query(type); 

    // If the class is not registered, return None. 
    if (!registration) return python::object(); 

    python::handle<PyTypeObject> handle(python::borrowed(
    registration->get_class_object())); 
    return python::object(handle); 
} 

がでPythonのクラスオブジェクトを配置する完全な例demonstratingですBoost.Pythonレジストリ:

#include <boost/python.hpp> 
#include <iostream> 

/// @brief Get the class object for a wrapped type that has been exposed 
///  through Boost.Python. 
template <typename T> 
boost::python::object get_instance_class() 
{ 
    // Query into the registry for type T. 
    namespace python = boost::python; 
    python::type_info type = python::type_id<T>(); 
    const python::converter::registration* registration = 
    python::converter::registry::query(type); 

    // If the class is not registered, return None. 
    if (!registration) return python::object(); 

    python::handle<PyTypeObject> handle(python::borrowed(
    registration->get_class_object())); 
    return python::object(handle); 
} 

struct spam {}; 

int main() 
{ 
    Py_Initialize(); 

    namespace python = boost::python; 
    try 
    { 
    // Create the __main__ module. 
    python::object main_module = python::import("__main__"); 
    python::object main_namespace = main_module.attr("__dict__"); 

    // Create `Spam` class. 
    // >>> class Spam: pass 
    auto spam_class_object = python::class_<spam>("Spam", python::no_init); 
    // >>> print Spam 
    main_module.attr("__builtins__").attr("print")(get_instance_class<spam>()); 
    // >>> assert(spam is spam) 
    assert(spam_class_object.ptr() == get_instance_class<spam>().ptr()); 
    } 
    catch (python::error_already_set&) 
    { 
    PyErr_Print(); 
    return 1; 
    } 
} 

出力:

<class 'Spam'> 

タイプオブジェクトを受け入れるなどのタイプ関連の機能については、isおよびissubclassを参照してください。this答えを参照してください。

関連する問題