2011-01-17 8 views
7

Tôi đang gặp sự cố với SWIG, con trỏ được chia sẻ và kế thừa.SWIG, tăng con trỏ được chia sẻ và thừa kế

Tôi đang tạo các lớp C++ khác nhau kế thừa nhau, sử dụng Tăng con trỏ được chia sẻ để tham chiếu đến chúng, sau đó gói các con trỏ chia sẻ với SWIG để tạo các lớp python.

Vấn đề của tôi là như sau:

  • B là một lớp con của A
  • Sa là một con trỏ chia sẻ đến A
  • SB là một con trỏ chia sẻ đến B
  • f (SA) là hàm mong muốn một con trỏ được chia sẻ tới A

  • Nếu tôi chuyển sB thành f() thì lỗi sẽ được tăng lên.

  • Lỗi này chỉ xảy ra ở cấp độ trăn.
  • Ở cấp độ C++ tôi có thể chuyển sB sang f() mà không gặp sự cố.

Tôi đã tăng 1,40 và xoay 1,3,40.

Dưới đây là nội dung của 5 tác phẩm mà sẽ tạo lại vấn đề với:

python setup.py build_ext --inplace 
python test.py 

swig_shared_ptr.h

#ifndef INCLUDED_SWIG_SHARED_PTR_H 
#define INCLUDED_SWIG_SHARED_PTR_H 

#include <boost/shared_ptr.hpp> 

class Base {}; 

class Derived : public Base {}; 

typedef boost::shared_ptr<Base> base_sptr; 
typedef boost::shared_ptr<Derived> derived_sptr; 

void do_something (base_sptr bs); 

base_sptr make_base(); 
derived_sptr make_derived(); 

#endif 

swig_shared_ptr.cc

#include <iostream> 
#include "swig_shared_ptr.h" 

void do_something (base_sptr bs) 
{ 
    std::cout << "Doing something." << std::endl; 
} 

base_sptr make_base() { return base_sptr(new Base()); }; 
derived_sptr make_derived() { return derived_sptr(new Derived()); }; 

swig_shared_ptr.i

%module(docstring=" 
Example module showing problems I am having with SWIG, shared pointers 
and inheritance. 
") swig_shared_ptr 

%{ 
#include "swig_shared_ptr.h" 
%} 

%include <swig_shared_ptr.h> 
%include <boost_shared_ptr.i> 
%template(base_sptr) boost::shared_ptr<Base>; 
%template(derived_sptr) boost::shared_ptr<Derived>; 

setup.py

""" 
setup.py file for swig_shared_ptr 
""" 

from distutils.core import setup, Extension 

swig_shared_ptr_module = Extension('_swig_shared_ptr', 
         include_dirs = ['/usr/include/boost'], 
         sources=['swig_shared_ptr.i', 'swig_shared_ptr.cc'], 
         ) 

setup (name = 'swig_shared_ptr', 
     version = '0.1', 
     author = "Ben", 
     description = """Example showing problems I am having with SWIG, shared 
         pointers and inheritance.""", 
     ext_modules = [swig_shared_ptr_module], 
     py_modules = ["swig_shared_ptr"], 
     ) 

test.py

import swig_shared_ptr as ssp 

bs = ssp.make_base() 
dr = ssp.make_derived() 

# Works fine. 
ssp.do_something(bs) 
# Fails with "TypeError: in method 'do_something', argument 1 of type 'base_sptr'" 
ssp.do_something(dr) 

Trả lời

4

Thay đổi sau đây sẽ xuất hiện để khắc phục sự cố.

Trong swig_shared_ptr.i hai dòng:

%template(base_sptr) boost::shared_ptr<Base>; 
%template(derived_sptr) boost::shared_ptr<Derived>; 

đang di chuyển để họ trên đường

%include <swig_shared_ptr.h> 

và sau đó được thay thế (trong SWIG 1.3) bởi:

SWIG_SHARED_PTR(Base, Base) 
SWIG_SHARED_PTR_DERIVED(Derived, Base, Derived)  

hoặc (trong SWIG 2.0) theo:

%shared_ptr(Base) 
%shared_ptr(Derived) 
3

SWIG không biết gì về lớp boost::shared_ptr<T>. Do đó, không thể nói rằng derived_sptr có thể được "bỏ" (tức là, tôi tin rằng, được thực hiện với một số nhà xây dựng và lập trình meta mẫu) đến derived_sptr. Vì SWIG yêu cầu các định nghĩa lớp đơn giản (hoặc bao gồm các tệp đơn giản với %include), bạn sẽ không thể khai báo chính xác lớp shared_ptr, vì Boost là vô cùng không đơn giản với bù biên dịch và thủ thuật mẫu của nó.

Đối với giải pháp: có cần thiết phải đưa ra các con trỏ được chia sẻ không? Trình bao bọc C++ của SWIG về cơ bản hoạt động như các con trỏ được chia sẻ. Boost và SWIG rất, rất khó để làm việc cùng nhau.

+0

Cảm ơn bạn đã trả lời. Bây giờ tôi biết tại sao tôi gặp rất nhiều rắc rối. –

+1

@gyroidben: Nếu điều này trả lời câu hỏi của bạn, hãy nhấp vào dấu kiểm bên cạnh câu trả lời của tôi. Ngoài ra, nếu sử dụng Python với tăng là rất quan trọng, bạn có thể muốn xem Boost :: Python, quá. –

+0

@gyroidben có các lựa chọn thay thế cho SWIG liên quan đến Python. Boost :: Python kết hợp với Py ++ tạo cùng kiểu tích hợp ngôn ngữ tự động nhưng có thể xử lý các kiểu Boost. – wheaties