2012-08-31 32 views
9

Tôi có một đối tượng được tổ chức trong một shared_ptr trong C + +. Đối tượng được truy cập thông qua các ràng buộc python từ bên trong python và được chuyển tới một hàm C++ bị ràng buộc khác mà cố giữ lại nó. Có vẻ như khi đối tượng chuyển từ C++ sang Python, nó được chuyển đổi từ một shared_ptr thành một đối tượng python. Sau đó, khi nó quay trở lại C++, nó được chuyển đổi từ đối tượng python thành một shared_ptr mới, tuy nhiên shared_ptr này không liên quan đến shared_ptr ban đầu.Có thể vượt qua một tăng shared_ptr từ C + + để Python và trở lại C++

Có thể thiết lập các ràng buộc tăng-python để chuyển đổi từ đối tượng python thành shared_ptr tham chiếu đến nội bộ shared_ptr gốc không?

Dưới đây là mã tóm lược mà tôi đã sử dụng để hiển thị sự cố.

Trong ví dụ này, một đối tượng ban đầu được giữ trong shared_ptr có tên là s_inital. Nó được lấy từ bên trong python thông qua hàm getSharedPtr, sau đó được đẩy trở lại C++ thông qua hàm putSharedPtr. Bên trong putSharedPtr nó được sao chép vào trong weak_ptr s_copied. Kiểm tra con trỏ trong trình gỡ rối cho thấy shared_ptr được sử dụng trong putSharedPtr không có cùng tham chiếu đếm nội bộ như s_initial. Xác nhận cuối cùng sẽ kích hoạt vì con trỏ yếu s_copied chỉ liên quan đến một con trỏ mạnh (con trỏ được sử dụng trong putSharedPtr) và con trỏ đó đã bị hủy khi putSharedPtr hoàn tất.

static shared_ptr<Captured> s_initial; 
static weak_ptr<Captured> s_copied; 

class UseSharedPtr 
{ 
public: 
    shared_ptr<Captured> getSharedPtr() 
    { 
     return s_initial; 
    } 

    void putSharedPtr(shared_ptr<Captured> ptr) 
    { 
     s_copied = ptr; 
    } 
}; 


BOOST_PYTHON_MODULE(test) 
{ 
    class_<Captured, shared_ptr<Captured>, boost::noncopyable>("Captured", no_init); 
    class_<UseSharedPtr, boost::noncopyable>("UseSharedPtr", init<>()) 
     .def("getSharedPtr", &UseSharedPtr::getSharedPtr) 
     .def("putSharedPtr", &UseSharedPtr::putSharedPtr) 
    ; 
} 



    s_initial = make_shared<Captured>(); 

    const char* chunk = "\ 
from test import UseSharedPtr \n\ 
x = UseSharedPtr() \n\ 
ptr = x.getSharedPtr() \n\ 
x.putSharedPtr(ptr)\n\ 
del x \n\ 
del ptr \n\ 
"; 
    object result = exec(chunk, mainNamespace, mainNamespace); 

    assert(s_copied.lock()); 
+0

Mục đích của toàn bộ lớp 'UseSharedPtr' là gì? Cũng giống như 'Captured' được hiển thị ngay bây giờ, boost :: python sẽ xử lý chính xác. – eudoxos

+0

Tôi nghĩ đây chỉ là một ví dụ. Trong khi boost.python sẽ gọi chính xác các phương thức của lớp được chia sẻ, nó có vấn đề khi truyền tham số 'shared_ptr' thành các lớp khác. – Tali

Trả lời

0

Bạn cần class_<UseSharedPtr, shared_ptr<UseSharedPtr>, boost::noncopyable> để tăng :: python biết nên quản lý đối tượng bằng shared_ptr. Làm cho ví dụ của bạn có thể biên dịch nếu bạn muốn tôi xác minh điều đó.

+0

Cờ 'shared_ptr' và' noncopyable' đã xuất hiện trong ví dụ được đăng. – Tali

0

Cách giải quyết dễ dàng nhưng xấu xí là sử dụng enable_shared_from_this() cho lớp Captured và nhận shared_ptr mới cho mỗi thông số sử dụng shared_from_this().

void putSharedPtr(shared_ptr<Captured> ptr) 
{ 
    s_copied = ptr->shared_from_this(); 
} 
Các vấn đề liên quan