How make a *.t block

Looking inside gnuradio,I’ve found blocks like divide_XX where relative
files have an extension .t (like )…in this way,is
possible to manage different types for the same block.
How is posssible to create blocks like them? is necessary to use
parameters in gr_modtools?

I ask this because I didn’t found other clever way to manage multiple
type at the same time. I’ve tried with template, but it doesn’t
wotk(cmake/make work,but swig doesn’t work)…also making different
blocks(same function,different data type) which invoke the same
template(with different parameters) doesn’t work with swig,and crash
the others wrapper.


Hi Marco,

.t is for template, and at build time, the full implementations of these
blocks are generated, and then compiled.
gr_modtool doesn’t support that. However, the magic involved is not
really of the overly complex kind:

  • CMake writes a python program to do the substitutions
  • In the CMakeLists.txt, that program is applied to all templates
  • the resulting headers/C++ implementations are added to the list of
    files that need to be built and linked together

For reference, open up gr-blocks/lib/CMakeLists.txt, and have a look at
all the EXPAND lines; you’ll find the matching CMake routines in

SWIG should handle the templates well by now, but might be
exceptionally hard to tell it what to wrap (and what not). Also, the
classical templating problems arise: Unless you use a specific
template specialization, it never gets built – and in the end, SWIG
might try to wrap things that aren’t there; maybe
SWIG and C++ has an approach
that might work for you:

/* Instantiate a few different versions of the template */
%template(intList) List;
%template(doubleList) List;

so in your case, maybe something like

%template(marco_block_cc) marco_block<gr_complex>;

I haven’t tested this for a while, though.

The reason there’s these expanding templates instead of proper C++
templates in GNU Radio is for historical reasons (SWIG didn’t use to
handle templates at all), and for the reason that a block typically
doesn’t care about the data that it’s being handed at all (e.g. it just
memcpy from A to B), in which case a simple passing of the item size as
parameter is sufficient, or it cares a lot about the type, and needs a
different specialization for basically almost all implementations (e.g.
multiplying two floats is optimized differently than multiplying
complexes). So the reasonable thing to ask here is: Does your block fit
in either of these two categories?