/ / Boost.Python tworzy uchwyt z typu - python, c ++, boost-python

Boost.Python utworzyć uchwyt z typu - python, c ++, boost-python

W niektórych miejscach, wystawiając kod C ++ na python, muszę użyć a PyObject*. Jeśli mam wystąpienie a boost::python::class_ obiekt, mogę przywołać ptr() na tym. Ale co jeśli mam tylko typ?

Zasadniczo, biorąc pod uwagę listę typów boost::python::bases<A, B, C>, Chcę przekonwertować to na boost::python::tuple przypadków, które mogę przekazać w coś takiego PyErr_NewExceptionWithDoc(). czy to możliwe?

Odpowiedzi:

1 dla odpowiedzi № 1

Biorąc pod uwagę typ C ++ T, można stworzyć boost::python::type_id obiekt, a następnie zapytanie do rejestru Boost.Python w celu uzyskania informacji rejestracyjnych. Jeśli wpis znajduje się w rejestrze, można go użyć do uzyskania uchwytu klasy Python utworzonej dla typu T:

/// @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);
}

Oto kompletny przykład demonstrowanie zlokalizowanie obiektu klasy Python w rejestrze 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;
}
}

Wydajność:

<class "Spam">

Więcej funkcji związanych z typem, takich jak akceptowanie obiektów typu, is, i issubclass, widzieć to odpowiedź.