Hi Josh,
Thanks for the info. So, for example if I want to modify the blob_to_stream example as blob_to_blob (ie. input a message and then output a message). The .cc files is as shown below, but I got errors when I compile because of the type of variables:
In member function ‘virtual int blob_to_blob_impl::work(const InputItems&, const OutputItems&)’:
/lib/blob_to_blob.cc:78:43: error: no matching function for call to ‘blob_to_blob_impl::post_msg(int, const pmt_t&, const char*&, pmt::pmt_t&)’
/lib/blob_to_blob.cc:78:43: note: candidates are:
/grextras/include/gnuradio/block.h:204:10: note: void gnuradio::block::post_msg(size_t, const gr_tag_t&)
/grextras/include/gnuradio/block.h:204:10: note: candidate expects 2 arguments, 4 provided
/grextras/include/gnuradio/block.h:215:10: note: void gnuradio::block::post_msg(size_t, const pmt_t&, const pmt_t&, const pmt_t&)
/grextras/include/gnuradio/block.h:215:10: note: no known conversion for argument 3 from ‘const char*’ to ‘const pmt_t& {aka const boost::intrusive_ptr<pmt::pmt_base>&}’
The file blob_to_blob.cc is:
#include <gnuradio/extras/blob_to_blob.h>
#include <gr_io_signature.h>
#include <cstring> //std::memcpy
using namespace gnuradio::extras;
static const pmt::pmt_t BLOB_KEY = pmt::pmt_string_to_symbol("blob_stream"); //From stream to blob
class blob_to_blob_impl : public blob_to_blob{
public:
blob_to_blob_impl(const size_t item_size):
block(
"blob_to_blob",
gr_make_io_signature(0, 0, 0),
gr_make_io_signature(1, 1, item_size),
msg_signature(true, 1)
),
_item_size(item_size)
{
_offset = 0;
//From stream to blob example
std::stringstream str;
str << name() << unique_id();
_id = pmt::pmt_string_to_symbol(str.str());
}
int work(
const InputItems &input_items,
const OutputItems &output_items
){
//Here the blob is received
//loop until we get a blob or interrupted
while (_offset == 0){
_msg = this->pop_msg_queue(); //Reading the incoming blob
if (pmt::pmt_is_blob(_msg.value)) break;
}
if (pmt::pmt_blob_length(_msg.value) == 0) return -1; //empty blob, we are done here
//calculate the number of bytes to copy
const size_t nblob_items = (pmt::pmt_blob_length(_msg.value) - _offset)/_item_size;
const size_t noutput_bytes = _item_size*std::min<size_t>(output_items[0].size(), nblob_items);
//perform memcpy from blob to output items
const char *blob_mem = reinterpret_cast<const char *>(pmt::pmt_blob_data(_msg.value)) + _offset;
//std::memcpy(output_items[0].get(), blob_mem, noutput_bytes); //Putting in the output blob_mem
//post the message to downstream subscribers
//this->post_msg(0, BLOB_KEY, blob, _id);
this->post_msg(0, BLOB_KEY, blob_mem, _id); //Using blob mem
//adjust the offset into the blob memory
_offset += noutput_bytes;
if (pmt::pmt_blob_length(_msg.value) == _offset) _offset = 0;
return noutput_bytes/_item_size;
}
private:
const size_t _item_size;
gr_tag_t _msg;
size_t _offset;
pmt::pmt_t _id; //From strem to blob example
};
blob_to_blob::sptr blob_to_blob::make(const size_t item_size){
return gnuradio::get_initial_sptr(new blob_to_blob_impl(item_size));
}
Many thanks again for your kind help,
JoseOn Tue, Oct 9, 2012 at 4:25 AM, Josh Blum
<address@hidden> wrote:
On 10/07/2012 09:56 PM, Jose Torres Diaz wrote:
> Hi All,
>
> I have another question about the message passing technique. In this
> opportunity, I would like to create a block that takes message as input,
> but also that post message downstream as output. In my initial attempt, I'm
> using the original blob_to_stream example (see below), the incoming message
> is taken using:
>
> _msg = this->pop_msg_queue();
>
> and then, in order to output the incoming message, it is used:
>
> std::memcpy(output_items[0].get(), blob_mem, noutput_bytes);
>
> However,
>
> *(1) Is it possible to use an alternative way like this:
>
> post_msg(0,_msg.key, _msg.value,_id); ?
Yes, absolutely. This is the correct way to pass the message downstream.
-josh