[Top][All Lists]

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

Re: [Discuss-gnuradio] Code re-use in blocks / C++ inheritance with gr::

From: Marcus Müller
Subject: Re: [Discuss-gnuradio] Code re-use in blocks / C++ inheritance with gr::sync_block
Date: Tue, 22 Oct 2013 11:38:46 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.0

Hi Sylvain,

this is yet another incarnation of the diamond problem I discussed with Nemanja:

Your glfw_.._impl is a double indirect subclass to base_sink_c:
and thus, your glfw_sink_c_impl instance holds two separate instances of base_sink_c, therefore two instances of gr::basic_block and you won't necessarily connect the correct one (whichever that may be), and even if you did, the other one will be left unconnected, which also will lead to an error.
So: one of glfw_sink_c or base_sink_c must not inherit from gr::basic_block.
personally, I'd just not let glfw_sink_c_impl inherit from base_sink_c_impl, and move the common stuff directly to base_sink_c.


On 10/22/2013 10:49 AM, Sylvain Munaut wrote:

So what I'm trying to achieve is to share a lot of code (including the
gr::sync_block implementation for work/start/stop) and a common
interface between several gnuradio blocks.

What I have currently come up with is (short version, see bottom for
more complete version) :

class API base_sink_c : virtual public gr::sync_block {};
class API glfw_sink_c : virtual public base_sink_c {};

class base_sink_c_impl : virtual public base_sink_c {};
class glfw_sink_c_impl : public glfw_sink_c, public base_sink_c_impl {};

* base_sink_c is a collection of virtual methods that define the
common functionality between subblocks.
* glfw_sink_c is the interface of the 'glfw' variant (only one here
atm) and is a super-set of the one in base_sink_c.
* base_sink_c_impl is the implementation of all the common stuff,
including the start/stop/work of gr::sync_block
* glfw_sink_c_impl is the 'glfw' variant and is the class to be
instanciated, it contains all the glfw specific code.

But this doesn't seem to work ... it crashes when GR tries to attach
the block in the block graph ( backtrace http://pastebin.com/JeBUEgtK

This is the resulting C++ layout (dumped with -fdump-class-hierarchy )

Anyone has a clue what I'm doing wrong ?


    Sylvain Munaut


More complete version:

class API base_sink_c : virtual public gr::sync_block
  /* Common exposed interface stuff (all virtual) */

class API glfw_sink_c : virtual public base_sink_c
  typedef boost::shared_ptr<glfw_sink_c> sptr;
  static sptr make();

  /* + Interface stuff specific to this variant (all virtual) */

class base_sink_c_impl : virtual public base_sink_c
   base_sink_c_impl(const char *block_name);

   int work (int noutput_items,
                gr_vector_const_void_star &input_items,
                gr_vector_void_star &output_items);
   bool start();
   bool stop();

    /* all private stuff to the base implementation */

class glfw_sink_c_impl : public glfw_sink_c, public base_sink_c_impl
  virtual ~glfw_sink_c_impl();

Then on the implementation side I have :

base_sink_c_impl::base_sink_c_impl(const char *block_name)
  : gr::sync_block(block_name,
                   gr::io_signature::make(1, 1, sizeof(gr_complex)),
                   gr::io_signature::make(0, 0, 0))
  /* block specific stuff */

        return gnuradio::get_initial_sptr(new glfw_sink_c_impl());

  : base_sink_c_impl("glfw_sink_c")
       /* ... */

Discuss-gnuradio mailing list

reply via email to

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