Получение None в качестве аргумента в boost.python

148
23 декабря 2019, 16:20

Пытаюсь экспортировать из С++ в Python перегруженную функцию, которая должна принимать, в том числе, None. Непонятно какой тип данных следует использовать в этом случае в качестве типа аргумента на стороне C++?

пример C++:

void foo_void()                     {  std::cout<<__FUNCTION__ <<std::endl; }
void foo_str (std::string)          {  std::cout<<__FUNCTION__ <<std::endl; }
void foo_int (int        )          {  std::cout<<__FUNCTION__ <<std::endl; }
void foo_dbl (double     )          {  std::cout<<__FUNCTION__ <<std::endl; }
void foo_none(nullptr_t  )          {  std::cout<<__FUNCTION__ <<std::endl; } //< что использовать здесь вместо nullptr_t ?
using namespace boost::python;
BOOST_PYTHON_MODULE( test_variant )
{
    def( "foo"    , &foo_void  );
    def( "foo"    , &foo_str   );
    def( "foo"    , &foo_int   );
    def( "foo"    , &foo_dbl   );
    def( "foo"    , &foo_none  );
}

python:

foo()
foo(1)
foo(1.0)
foo("Foo")
foo(None)

Выдает ошибку в последней сроке:

Traceback (most recent call last):
  File "test.py", line 12, in <module>
    foo(None)
Boost.Python.ArgumentError: Python argument types in
    test_variant.foo(NoneType)
did not match C++ signature:
    foo(std::nullptr_t)
    foo(double)
    foo(int)
    foo(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)
    foo(void)
Answer 1

Получилось реализовать перегрузку функции для типа None, введя дополнительный собственный тип, и зарегистрировав конвертер:

struct none_type
{
    none_type() {}
    none_type(const none_type&) {}
    none_type(none_type&&) {}
    none_type& operator = (const none_type&) { return *this; }
    none_type& operator = (none_type&&)      { return *this; }
    bool operator == (const none_type&) const { return true; }
};
template<typename T>
struct convertible_from_Py_None
{
    convertible_from_Py_None()
    {
        converter::registry::push_back(&convertible_from_Py_None::convertible,
                                       &convertible_from_Py_None::construct,
                                       type_id<T>());
    }
    static void* convertible(PyObject* obj_ptr)
    {
        return (Py_None==obj_ptr) ? obj_ptr : nullptr;
    }
    static void construct(PyObject* obj_ptr,
                          converter::rvalue_from_python_stage1_data* data)
    {
        assert(Py_None==obj_ptr);
        typedef converter::rvalue_from_python_storage<T> storage_t;
        storage_t* the_storage = reinterpret_cast<storage_t*>(data);
        void* memory_chunk = the_storage->storage.bytes;
        object obj(handle<>(borrowed(obj_ptr)));
        T* output = new (memory_chunk) T();
        // Use the contents of obj to populate output, e.g. using extract<>
        data->convertible = memory_chunk;
    }
};

Использование:

...
void foo_none(none_type)          {  std::cout<<__FUNCTION__ <<std::endl; } 
...
BOOST_PYTHON_MODULE( test_variant )
{
    convertible_from_Py_None<none_type>();
    ...
    def( "foo"    , &foo_none  );
    ...
}
READ ALSO
Как определить путь к текстуре модели в Arcgis?

Как определить путь к текстуре модели в Arcgis?

Можно менять текстуру у добавленной модели в Arcgis ? У меня добавляется модель на сцену так :

152
Передача id от одной таблицы к другой. Hibernate

Передача id от одной таблицы к другой. Hibernate

У меня есть две таблицы: customers и phoneNumbers У одного customer может быть 1+ phoneNumbers

157
Как правильно настроить роутинг в Spring Cloud Gateway

Как правильно настроить роутинг в Spring Cloud Gateway

Пытаюсь настроить роутинг в Gateway в properties прописываю адрес и куда перенаправлять, не могу понять логику работы

138
Вывод на экран плавающего виджета

Вывод на экран плавающего виджета

Столкнулся с задачей: вывести на экран плавающий виджет, чтобы его можно было перемещать, взаимодействовать с нимВиджет НЕ для рабочего стола,...

151