我有一個創建對象(類A的實例)的庫,並將它們傳遞給應該能夠調用其方法的python程序。將C++類實例傳遞給python並使用boost :: 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> >();
}
代碼缺少其中蟒蛇得到existing_instance
的一部分。我沒有粘貼,但我們只是說我爲此使用了回調機制。
此代碼的工作,但我有幾個問題:
在計數功能(和所有其他C++操作函數)是精細傳遞
a
一樣,或者最好是像做const shared_ptr<A>&
?在我在python boost文檔中找到的代碼片段中,經常使用該引用,但我不瞭解其中的差別(當然,除了具有較高的引用計數器外)。此代碼是否「安全」?當我將existing_instance傳遞給python時,它的計數器會增加(只是一次,即使在python中,我也會創建更多的對象副本),所以沒有辦法讓C++代碼可以銷燬對象,只要python成立至少一個「複製」。我對麼?我試圖玩弄指針,似乎我是正確的,我只是想確定一下。
我想阻止python創建實例A.他們應該只能從C++代碼傳遞。我怎麼能做到這一點? 編輯:發現,我只需要使用NO_INIT和不可複製:
class_<A, boost::noncopyable>("A", no_init)
什麼之間的區別(實際上) 「class_ (」 A 「NO_INIT)」 和「提升: :python :: class_ >(「A」,boost :: python :: no_init)「? 即使沒有在「class_」之後指定「boost :: shared_ptr 」,我發佈的代碼仍然完美。那麼,爲什麼我需要這個? – Emiliano 2010-08-01 16:27:33
它指定了實際上由python「A」包裝的默認類型 - 所以如果你有一個C++函數返回一個'A','A *'shared_ptr或者類似的東西,並且暴露給python,那麼返回值將被保存爲shared_ptr - 如果您經常將這些對象傳入或傳出python,那麼它將會被正確處理。 有關更多信息,請參見http://www.boost.org/doc/libs/1_43_0/libs/python/doc/v2/class.html#HeldType(尤其是第2點)。 – James 2010-08-01 17:32:46