Hi,
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 )
http://pastebin.com/raw.php?i=cDWQQwHn
Anyone has a clue what I’m doing wrong ?
Cheers,
Sylvain M.
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
{
public:
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
{
protected:
base_sink_c_impl(const char *block_name);
public:
int work (int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items);
bool start();
bool stop();
private:
/* all private stuff to the base implementation */
}
class glfw_sink_c_impl : public glfw_sink_c, public base_sink_c_impl
{
public:
glfw_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 */
}
glfw_sink_c::sptr
glfw_sink_c::make()
{
return gnuradio::get_initial_sptr(new glfw_sink_c_impl());
}
glfw_sink_c_impl::glfw_sink_c_impl()
: base_sink_c_impl(“glfw_sink_c”)
{
/* … */
}