передача экземпляров классов C ++ в python с boost :: python

У меня есть библиотека, которая создает объекты (экземпляры класса A) и передает их в программу python, которая должна иметь возможность вызывать их методы.

В основном у меня есть экземпляры класса C ++, и я хочу использовать их из python. Иногда этот объект должен быть передан обратно на C ++ для некоторых манипуляций.

Я создал следующий файл-оболочку (предположим, что функция New вызывается где-то в коде C ++):

 #include <boost/python.hpp> #include <iostream> #include <boost/smart_ptr.hpp> using namespace boost; using namespace boost::python; int calls = 0; struct A { int f() { return calls++; } ~A() { std::cout << "destroyed\n"; } }; shared_ptr<A> existing_instance; void New() { existing_instance = shared_ptr<A>( new A() ); } int Count( shared_ptr<A> a ) { return a.use_count(); } BOOST_PYTHON_MODULE(libp) { class_<A>("A") .def("f", &A::f) ; def("Count", &Count); register_ptr_to_python< shared_ptr<A> >(); } 

В коде отсутствует часть, в которой python получает existing_instance . Я не вставлял это, но давайте просто скажем, что для этой цели я использую механизм обратного вызова.

Этот код работает, но у меня есть несколько вопросов:

  1. В функции Count (и во всех других функциях манипуляции с C ++) это прекрасно, чтобы передать подобное, или лучше сделать что-то вроде const shared_ptr<A>& ? В фрагментах кода, которые я нашел в документации по повышению python, часто используется ссылка, но я не понимаю разницы (конечно, если у вас больше счетчик ссылок).

  2. Является ли этот код «безопасным»? Когда я передаю существующий_инстамент на python, его счетчик будет увеличиваться (только один раз, даже если в python я делаю больше копий объекта, конечно), поэтому нет никакого способа, чтобы код C ++ мог уничтожить объект, поскольку python имеет место по крайней мере, «копией». Я прав? Я пытался играть с указателями, и, похоже, я прав, я просто хочу быть уверенным.

  3. Я бы хотел, чтобы python не создавал экземпляры A. Они должны быть переданы только из кода C ++. Как я мог это достичь? EDIT : found, мне просто нужно использовать no_init и noncopyable: class_<A, boost::noncopyable>("A", no_init)

2 Solutions collect form web for “передача экземпляров классов C ++ в python с boost :: python”

boost::python знает все о boost::shared_ptr , но вам нужно сказать, что boost::shared_ptr<A> содержит экземпляр A , вы делаете это, добавляя boost::shared_ptr<A> в список аргументов шаблона, чтобы class_ , более подробная информация об этом «Held Type» приведена в документации по ускорению .

Чтобы предотвратить создание экземпляров из python, вы добавляете boost::python::no_init в конструктор class_, поэтому в итоге вы получаете:

 boost::python::class_< A, boost::shared_ptr<A> >("A", boost::python::no_init) //... .def, etc ; 

В общем случае вы не должны передавать общие указатели по ссылке, так как если ссылка на общий указатель недействительна, то ссылка, на которую указывает указатель общего указателя, также недействительна (поскольку использование ссылки общего указателя не увеличилось контрольный счетчик к указанному объекту).

Совершенно безопасно передавать объекты boost::shared_ptr вокруг и из python, количество ссылок (python и shared_ptr) будет правильно управляться, если вы не измените return_value_policy . Если вы измените политику метода, выставленного на python, чтобы он возвращал ссылку на общий указатель, тогда вы можете создавать проблемы, так же, как передача общих указателей вокруг ссылок c ++ может вызвать проблемы.

(Кроме того, вы должны использовать make_shared<A>(...) в предпочтении shared_ptr<A>(new A(...)) .)

В этой ситуации мой код будет выглядеть так (для вашего примера):

 ... BOOST_PYTHON_MODULE(libp) { class_<A, boost::shared_ptr<A>, boost::noncopyable >("A") .def("f", &A::f) .def("Count", &Count) ; } 

Важно запретить boost :: python копировать вещи, но если вы используете shared_ptr, возможно, вам нужно только копировать в нескольких контролируемых ситуациях.

  • вызов функции Cython из C ++
  • Лучший язык программирования для обработки медицинских изображений
  • Значительное пробел в C #, например Python или Haskell?
  • Как применить карту типа SWIG для аргумента struct с двойной указателем
  • Какой язык программирования имеет очень короткую контекстно-свободную грамматику в ее формальной спецификации?
  • Как использовать scipy.weave.inline вместе с внешними библиотеками C?
  • Создание объекта с использованием API Python C
  • libclang: добавить систему компилятора include path (Python в Windows)
  •  
    Interesting Posts for Van-Lav

    Сравнение на основе функции min

    изменение глобальной переменной при многопроцессорности в python

    использование ключей JSON в качестве атрибутов python во вложенном JSON

    Как преобразовать Spark RDD в pandas dataframe в ipython?

    Как распечатать дату и время Python в локальном часовом поясе?

    Как отправлять и извлекать blob с Django

    Самый быстрый побитовый xor между двумя многобайтовыми двоичными переменными данных

    Python: как определить время выполнения имени аргумента

    Являются ли постоянные вычисления кэшированными в Python?

    Как создать файл excel с автофильтром в первой строке с помощью xlwt?

    Python: в чем разница между модулями многопоточности и многопроцессорности?

    Запуск формы Tkinter в отдельном потоке

    создание scipy.lil_matrix с использованием генератора питона эффективно

    Удалите дубликаты в списке, сохраняя при этом его порядок (Python)

    Python Совместное использование сетевого сокета с multiprocessing.Manager

    Python - лучший язык программирования в мире.