Download the file gr-howto-write-a-block-3.3.0.tar.gz from
http://gnuradio.org/releases/gnuradio/gr-howto-write-a-block-3.3.0.tar.gz
Naming convention for block names :
After we create our block the only way we can use it in GNU Radio is to create a python script which loads the package/module containing the our block, and then connect our block to the GNU Radio flow graph
It will be something like this :
from package_name import module_name
new_block = module_name.block_name()
There is an important key coupling between the module and block names which we invoke in python, and the names used in the coding blocks of C++
GNU Radio expects that all the C++ source and header files are in the form [module_name]_[block_name].h and [module_name]_[block_name].cc
Hence if we decided to name our C++ class as newModule_newBlock, then GNU Radio's build system would make our block available from python in module "newModule" and with block name "newBlock"
Naming convention for boost smart pointers :
All pointers to the GNU Radio blocks must use boost shared pointers and not the regular C++ pointers
If we create a new C++ signal processing block called "newModule_newBlock" then GNU Radio's internal implementation will not work if we use a regular C++ pointer to newBlock_newFunction in our code
In other words the command
newModule_newBlock* ptr newBlock_newFunction() wont work in GNU Radio
This rule is enforced by making all the block constructors private and ensures that a regular C++ pointer can never point to a block object
But if the constructor is private, how do we create new instance of our block , after all we need some pubic interface for creating new block instances
The solution is to declare a friend function !!
This is done by first declaring a friend function of the class, so that it has access to all the private members of the class including the private constructor
This friend function invokes the private constructor and returns a smart pointer to it
We invoke this friend function everytime we want to construct a new object of the class
Suppose the name of our new signal processing block is newModule_newBlock_cc , then we would create a file newModule_newBlock_cc.cc , in which we would include the following function declaration :
typedef boost::shared_ptr newModule_newBlock_cc_sptr
friend newModule_newBlock_cc_sptr newModule_make_newBlock_cc()
Now the function newModule_make_newBlock_cc has access to the private members of the class newModule_newBlock_cc
The final step is to cast the return pointer's data type from raw C++ pointer to a smart pointer
newModule_newBlock_cc_sptr newModule_make_newBlock_cc() () {
return newModule_newBlock_cc_sptr (new newModule_newBlock_cc());
}
By the way the private constructor which can be invoked directly is some thing like as follows :
newModule_newBlock_cc() {
gr_block("newBlock_cc",
gr_makeio_signature (1,1, sizeof (gr_complex)),
gr_make_iosignature (1,1, sizeof (gr_complex))
)
}
So to summarize, the private constructor is actually creating a new gr_block object
The "friend constructor" which is the public interface to the private constructor
, acts as a surrogate by wrapping the new object created by the private constructor into a boost shared pointer
This complex procedure ensures that all the pointers to the block are boost smart pointers
The public interface for creating objects is actually not the object constructor newModule_newBlock_cc but rather the "surrogate" constructor newModule_make_newBlock_cc
So in our code we must use the following code to create a new block object nb :
newModule_newBlock_cc_sptr nb = newModule_make_newBlock_cc()
One important point to be mentioned here : if one's block name is newModule_newBlock_cc then the name of the shared pointer to this block MUST be newModule_newBlock_cc_sptr
Any other choice would lead to code not working properly
The above naming has nothing to do with the C++ , but when this C++ block is invoked from python in a GNU Radio program , GNU Radio expects the name of shared pointer to follow directly from the block name with an appended _sptr to it, or else it will complain that it couldn't find the block
Also the surrogate constructor which creates a shared pointer to newModue_newBlock_cc must have signature
newModule_newBlock_cc_sptr newModule_make_newBlock_cc()
*Note the presence of the word make between newModule and newBlock
Reference : http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADA556803
http://gnuradio.org/releases/gnuradio/gr-howto-write-a-block-3.3.0.tar.gz
Naming convention for block names :
After we create our block the only way we can use it in GNU Radio is to create a python script which loads the package/module containing the our block, and then connect our block to the GNU Radio flow graph
It will be something like this :
from package_name import module_name
new_block = module_name.block_name()
There is an important key coupling between the module and block names which we invoke in python, and the names used in the coding blocks of C++
GNU Radio expects that all the C++ source and header files are in the form [module_name]_[block_name].h and [module_name]_[block_name].cc
Hence if we decided to name our C++ class as newModule_newBlock, then GNU Radio's build system would make our block available from python in module "newModule" and with block name "newBlock"
Naming convention for boost smart pointers :
All pointers to the GNU Radio blocks must use boost shared pointers and not the regular C++ pointers
If we create a new C++ signal processing block called "newModule_newBlock" then GNU Radio's internal implementation will not work if we use a regular C++ pointer to newBlock_newFunction in our code
In other words the command
newModule_newBlock* ptr newBlock_newFunction() wont work in GNU Radio
This rule is enforced by making all the block constructors private and ensures that a regular C++ pointer can never point to a block object
But if the constructor is private, how do we create new instance of our block , after all we need some pubic interface for creating new block instances
The solution is to declare a friend function !!
This is done by first declaring a friend function of the class, so that it has access to all the private members of the class including the private constructor
This friend function invokes the private constructor and returns a smart pointer to it
We invoke this friend function everytime we want to construct a new object of the class
Suppose the name of our new signal processing block is newModule_newBlock_cc , then we would create a file newModule_newBlock_cc.cc , in which we would include the following function declaration :
typedef boost::shared_ptr
friend newModule_newBlock_cc_sptr newModule_make_newBlock_cc()
Now the function newModule_make_newBlock_cc has access to the private members of the class newModule_newBlock_cc
The final step is to cast the return pointer's data type from raw C++ pointer to a smart pointer
newModule_newBlock_cc_sptr newModule_make_newBlock_cc() () {
return newModule_newBlock_cc_sptr (new newModule_newBlock_cc());
}
By the way the private constructor which can be invoked directly is some thing like as follows :
newModule_newBlock_cc() {
gr_block("newBlock_cc",
gr_makeio_signature (1,1, sizeof (gr_complex)),
gr_make_iosignature (1,1, sizeof (gr_complex))
)
}
So to summarize, the private constructor is actually creating a new gr_block object
The "friend constructor" which is the public interface to the private constructor
, acts as a surrogate by wrapping the new object created by the private constructor into a boost shared pointer
This complex procedure ensures that all the pointers to the block are boost smart pointers
The public interface for creating objects is actually not the object constructor newModule_newBlock_cc but rather the "surrogate" constructor newModule_make_newBlock_cc
So in our code we must use the following code to create a new block object nb :
newModule_newBlock_cc_sptr nb = newModule_make_newBlock_cc()
One important point to be mentioned here : if one's block name is newModule_newBlock_cc then the name of the shared pointer to this block MUST be newModule_newBlock_cc_sptr
Any other choice would lead to code not working properly
The above naming has nothing to do with the C++ , but when this C++ block is invoked from python in a GNU Radio program , GNU Radio expects the name of shared pointer to follow directly from the block name with an appended _sptr to it, or else it will complain that it couldn't find the block
Also the surrogate constructor which creates a shared pointer to newModue_newBlock_cc must have signature
newModule_newBlock_cc_sptr newModule_make_newBlock_cc()
*Note the presence of the word make between newModule and newBlock
Reference : http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADA556803
No comments:
Post a Comment