Menu

#1215 shared_ptr to STL container requires fully-specified types

open
nobody
5
2022-03-19
2011-12-20
Anonymous
No

When declaring a %shared_ptr to a %template type declaration, SWIG requires you to specify the full type in the %shared_ptr statement; otherwise it only provides an opaque SwigPyObject (for example) in the target language. Fully specifying the type in the %shared_ptr statement instead of referring to a typedef'ed name allows correct access to the underlying object.

Credit to Johan Hake for the workaround:
https://sourceforge.net/mailarchive/message.php?msg_id=28566272

Original message to the list is below, with an attached example.

---

I am trying to wrap a C++ library which passes around boost::shared_ptr's to STL containers (set, map, etc). It was easy enough to wrap shared_ptr<Object>, and set<shared_ptr<Object> > and make use of those objects and C++ methods from Python, but whenever I try to wrap shared_ptr< set < shared_ptr<Object> > >, the object I get back in Python is just a SwigPyObject that I can't seem to do anything useful with. Google didn't help much.

It seems like I need some sort of combination of %shared_ptr() and %template(), but I can't quite figure out how that would work. Is a shared_ptr to an STL container supported?

I suppose I could embed some CPython code that would convert between the shared_ptr<stl-container> and the Python object, but that just seems ugly and would add lots of runtime/copy overhead.

A sample interface file is attached. I can make and modify Foo and FooSet objects easily enough. However, the pset_copy, pset_deref, and get_pset functions hand me a worthless SwigPyObject in Python. I also can't use add_to_pset or add_to_set inside of Python, since any FooSet objects I make aren't the right type.

Output from swig version 2.0.4 follows.

---
swig -v -debug-classes -python -c++ -Wall -I../include -o test2_wrap.cpp test2.i
Language subdirectory: python
Search paths:
./
../include/
./swig_lib/python/
/opt/local/share/swig/2.0.4/python/
./swig_lib/
/opt/local/share/swig/2.0.4/
Preprocessing...
Starting language-specific parse...
Processing types...
C++ analysis...
Generating wrappers...
Classes
------------
std::out_of_range
std::allocator
std::invalid_argument
std::set<(boost::shared_ptr<(test::Foo)>)>
boost::shared_ptr
boost::shared_ptr<(test::FooSet_p)>
boost::shared_ptr<(q(const).test::FooSet_p)>
boost::shared_ptr<(test::Foo)>
boost::shared_ptr<(q(const).test::Foo)>
boost::shared_ptr<(test::FooSet)>
boost::shared_ptr<(q(const).test::FooSet)>
std::length_error
std::exception
std::domain_error
std::bad_exception
std::set
std::pair<(p.T,U)>
test::Foo
std::runtime_error
std::range_error
std::overflow_error
std::logic_error
std::underflow_error
std::allocator<(void)>
std::pair<(T,p.U)>
std::pair<(p.T,p.U)>
swig::SwigVar_PyObject
swig::SwigPtr_PyObject
std::pair
swig::SwigPyIterator
swig::stop_iteration

Discussion

  • Olly Betts

    Olly Betts - 2022-03-19

    I think this is still the case with git master - for example _wrap_pset_copy sets the resultobj to an opaque type:

        resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), SWIGTYPE_p_boost__shared_ptrT_test__FooSet_p_t, SWIG_POINTER_OWN);
    
     

Log in to post a comment.