| Newsgroups |
gmane.comp.programming.swig |
| Message-ID |
<[email protected]> |
Good morning,
I have a question to get my bearing (new to swig).
Context: C++ to Python.
Say I have a factory method in C++ `std::vector<shared_ptr<Foo>>
makeFooVec()` and that I already exposed `Foo` (a C++ class) via SWIG as
well. I want to be able to invoke the factory method and get back an
array of _Python Proxy objects_ on the `Foo` instances in the C++
vector. It seems that `typemaps` are the answer. I'm assuming that
others must have solved that already.
Any suggestion on how to go ? (I read the documentation as well as this
slide deck (https://www.dabeaz.com/SwigMaster/SWIGMaster.pdf) which
nudged me in the direction of typemaps.
I did make some progress (relayed below) and I can share what didn’t
quite work. The above is a simplification of the real code (I really
have a sub-class of `std::vector`, a custom smart pointer type
(`handle_ptr<T>`) and `Foo` is really a class `var<int>` … but the
above should convey the essence). As you might expect, I’m not getting
what I want from the current wrapper.
Specifically:
1. The wrapper produces an PySwigObject for the std::vector<…>, not an
instance of the type I specified in the %template. When I see is:
```
<Swig Object of type 'EVec< handle_ptr< var< int > >,stl::StackAdapter<
handle_ptr< var< int > >,handle_ptr< Storage > > > *' at 0x107851b70>
```
Where EVec is the subtype of `std::vector`. So I didn’t get a python
array for my C++ vector (But there is a wrapper for it in the generated
.py file!). If I try to print(dir(x)) where `x` is that vector, I see:
```
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__',
'__init__', '__init_subclass__', '__int__', '__le__', '__lt__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'acquire',
'append', 'disown', 'next', 'own']
```
which is not the API of an array in python.
If I do `print(type(x))` I get:
```
<class 'SwigPyObject'>
```
Which is not the expected outcome. So the factory method returned a
“raw” SwigPyObject and didn’t proxy it. Here is the C++ API for
it:
```
namespace Factory {
…
EVec<var<int>::Ptr,alloci> intVarArray(CPSolver::Ptr cps,int sz,int
min,int max);
…
}
```
And I do have a %template for its return type
```
%template(VecVarInt)
std::vector<handle_ptr<var<int>>,stl::StackAdapter<handle_ptr<var<int>>,handle_ptr<Storage>>>;
%template(EVecVarInt)
EVec<handle_ptr<var<int>>,stl::StackAdapter<handle_ptr<var<int>>,handle_ptr<Storage>>>;
```
Note that `VecVarInt` is the vanilla `std::vector` (the parent class of
`EVec`) and I used template on both `std::vector` and
`EVec`. (`var<int>` is the `Foo` I’m talking about).
2. Besides, The things embedded in that object are not proxies to those
`Foo` (`var<int>` in the above).
Hence two questions:
- How do I get SWIG to wrap the result of the factory method property ?
- How do I get SWIG to generate a container that holds proxies to the
objects inside the vector ?
Any pointers most welcomed!
Thanks & Happy New Year.
—
Laurent
_______________________________________________
Swig-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/swig-user