C++ To Python

[email protected]
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.