discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Discuss-gnuradio] swig smart pointer inheritance issue


From: Rick Spanbauer
Subject: Re: [Discuss-gnuradio] swig smart pointer inheritance issue
Date: Sun, 15 Sep 2013 12:04:01 -0400

I spent some time reading the .cxx files swig generates, and trying to understand how my
use of gr::digital::constellation_sptr was falling off the tracks relative to other, similar applications
in the master branch (for example ofdm_equalizer_simpledfe.cc).  I constructed a simplified
example where I was passed in gr::digital::constellation_rect::sptr, without any subclassing to
the base constellation class, and still got type errors.  Which was puzzling.  This issue didn't seem
related to my build environment, since other examples I built using simple types (floats, doubles, etc)
as parameters worked fine.

What seemed to work for me was to be very literal in declaring the constellation class parameter
to my MER block as boost::shared_ptr<gr::digital::constellation> rather than using the
constellation_sptr typedef from constellation.h.  So the constructor for my MER block looks
like this:

    mer::sptr
    mer::make(boost::shared_ptr<gr::digital::constellation> mod_const, int decim_rate)
    {
      return gnuradio::get_initial_sptr (new mer_impl(mod_const, decim_rate));
    }

And can be called from from python, as I have in the following example:

#!/usr/bin/python
from qam_demod import mer
from gnuradio import digital

cnst = digital.constellation_qpsk()
print "type(c) = ", type(cnst)
print "type(c.base()) = ", type(cnst.base())
m = mer(cnst.base(), 4096)

I did try importing constellation.i in the module swig .i file; this didn't seem to help - constellation.i
has a few template definitions for the useful constellation classes of interest to me.

I'm still trying to understand the swig reason as to why this workaround is necessary - certainly the 
section on the complications that namespaces introduce, especially so given some of the
particular examples they give about typedefs and namespaces may provide some clues.

But at least I'm back to porting my 3.5 code to the 3.7 APIs, rather than spending time
squinting at swig's c++ files.


On Wed, Sep 11, 2013 at 11:44 AM, Tom Rondeau <address@hidden> wrote:
On Tue, Sep 10, 2013 at 7:44 PM, Rick Spanbauer <address@hidden> wrote:
> I'm converting some old blocks I wrote for ~3.5 gnuradio APIs to 3.7.  I
> have a block that
> calculates the MER of an incoming signal - this block is a synchronous
> decimator, and
> the make function takes a constellation_sptr and decimation rate as input:
>
> mer::sptr
>     mer::make(gr::digital::constellation_sptr mod_const, int decim_rate)
>     {
>       return gnuradio::get_initial_sptr (new mer_impl(mod_const,
> decim_rate));
>     }
>
> Note, I'm using gr_modtool to rough out all the details of building a module
> template & associated build system scaffolding.
>
> To test, I'm trying to pass in a constellation_rect_sptr, which is a
> subclass
> of the constellation class.  The relevant code snippet is this:
>
> def make_qam_constellation(pts):
>     return gr_qam.qam_constellation(constellation_points=pts,
> differential=False)
>
>
> When I pass in the constellation_rect_sptr, like this:
>
> #!/usr/bin/python
> from myqam import *
> from qam_demod import mer
> import gnuradio
>
> c = make_qam_constellation(256)
> print "type(c) = ", type(c)
> print "type(c.base()) = ", type(c.base())
> m = mer(c.base(), 4096)
>
>
> the swig type checker is throwing out the c.base() input:
>
> type(c) =  <class 'gnuradio.digital.digital_swig.constellation_rect_sptr'>
> type(c.base()) =  <class 'gnuradio.digital.digital_swig.constellation_sptr'>
> Traceback (most recent call last):
>   File "/home/rick/Z/test_mer.py", line 9, in <module>
>     m = mer(c.base(), 4096)
>   File "/usr/local/lib/python2.7/dist-packages/qam_demod/qam_demod_swig.py",
> line 95, in make
>     return _qam_demod_swig.mer_make(*args, **kwargs)
> TypeError: in method 'mer_make', argument 1 of type
> 'gr::digital::constellation_sptr'  <<<<<
>
> Just looking at the output from the two type() statements, the types seem
> proper, though
> the dotted notation vs '::' is interesting.
>
> I notice that Ben Reynwar posted a very similar issue back in 2010.  I had
> the same problem
> at the time, and resolved it via using the .base() method, apparently just
> as he did.  I suspect
> this issue, while similar, may have something to do with 3.7's use of
> namespaces, and some
> of the complexity of SWIG's processing of namespace.  I'm a definite SWIG
> neophyte, and
> perhaps I'm just missing something obvious, or at least I hope so.
>
> Has anyone run into this issue and found a resolution?  Looking at the .i
> files in the distribution
> didn't provide much in the way of inspiration as to how to solve the
> problem.
>
> Any pointers would be greatly appreciated.
>
> Rick Spanbauer


Hi Rick,

The problem isn't with 3.7 and the namespaces. You would have had to
use the '.base()' call on that block, even in the previous 3.6 way of
doing things. It's a larger issue of inheritance and managing classes
and shared pointers. But basically, when creating a constellation
class in Python and passing it as an argument to a
function/constructor, you need to return it as a shared pointer to the
parent class (gr::digital::constellation class in this case). If you
look at your constructor, you are asking for a 'constellation_sptr' as
the class of the input. But the qam_constellation will return
something derived from constellation (like constellation_rect_sptr).
Swig doesn't think these two are the same thing and won't let you do
it. So you recast the object as a consetllation_sptr and use that,
instead.

There could be a way around this in swig-land that we haven't really
looked into, though.

--
Tom
Visit us at GRCon13 Oct. 1 - 4
http://www.trondeau.com/grcon13


reply via email to

[Prev in Thread] Current Thread [Next in Thread]