2012-06-26 3 views
0

У меня есть python, встроенный в мое приложение, и я хочу отправить функцию python необработанным указателем на объект, который у меня есть в моем коде на C++.
Единственный способ, которым я нашел это, - это обернуть указатель auto_ptr или shared_ptr, но я не хочу этого делать, поскольку я не хочу, чтобы код python имел возможность удерживать ссылку на объект в мой код.boost python - как отправить необработанный указатель на функцию python>

Возможно ли это с boost :: python?

+0

Похоже, http://stackoverflow.com/a/5056462/138772 имеет ваше решение. «Передайте указатель объекта через boost :: python :: ptr на python, что не позволит интерпретатору python делать копию». – JAB

+0

@JAB Ницца! Напишите это как ответ, и я приму это. – shoosh

+0

На самом деле, кажется, я не смотрел в него достаточно/не читал то, что я скопировал и вставил правильно. Похоже, что использование 'boost :: python :: ptr' фактически сделает возможной зависание ссылок, скорее всего, по http://www.boost.org/doc/libs/1_49_0/libs/python/doc/v2 /ptr.html: «Обычно, при передаче указателей на обратные вызовы Python, копир копируется, чтобы гарантировать, что объект Python никогда не держит ссылку на свидание». – JAB

ответ

0

Если у вас есть сырой указатель на какой-либо объект C++, отображенные в Python, то вы можете сделать еще один объект Python вокруг первоначального указателя с помощью адаптера таким образом:

template<typename PtrT> 
struct PtrAdapter { 
    auto& get(PtrT ptr) { return *ptr; } 
}; 

Затем сделать это Python отображается тип и позволяют неявное преобразование:

class_<Cluster<LinksT>*, noncopyable>(typpedName<LinksT>("ClusterPtr", true, true) 
, "Raw hierarchy cluster pointer\n") 
    .def("__call__", &PtrAdapter<Cluster<LinksT>*>::get, 
     return_internal_reference<>(), 
     "referenced cluster") 
    ; 
register_ptr_to_python<Cluster<LinksT>*>(); 

Обратите внимание, что ссылки типа (в данном случае Cluster<LinksT>) также должны быть отображены на соответствующий объект Python.
Тогда для такого кода C++:

Cluster<LinksT>* cl = clusters.head(); 
process(cl); 
Id cid = cl->id(); 

Вы можете использовать подобный код Python:

cl = clusters.head() 
process(cl) 
cid = cl.id() 

Но если вам не нужны специальной обработки указателя на C++ объекта, то это, очевидно, лучше использовать boost::python::ptr.
Также вы должны рассмотреть альтернативы, упомянутые здесь: boost::python: howto call a function that expects a pointer?

Смежные вопросы