GNU Radio Manual and C++ API Reference 3.10.1.1
The Free & Open Software Radio Ecosystem
pycallback_object.h
Go to the documentation of this file.
1/* -*- c++ -*- */
2/*
3 * Copyright 2012 Free Software Foundation, Inc.
4 *
5 * This file is part of GNU Radio
6 *
7 * SPDX-License-Identifier: GPL-3.0-or-later
8 *
9 */
10
12#include <pythread.h>
13#include <boost/format.hpp>
14
15#include <iostream>
16
18
20
21// a simple to-PMT converter template class-function
22template <class myType>
24{
25public:
26 static pmt::pmt_t make(myType _val) { return pmt::mp(_val); }
27};
28
29/* template specializations for vectors that can't use pmt::mp() */
30template <>
31pmt::pmt_t pmt_assist<std::vector<float>>::make(std::vector<float> _val)
32{
33 return pmt::init_f32vector(_val.size(), _val);
34}
35
36template <>
37pmt::pmt_t pmt_assist<std::vector<gr_complex>>::make(std::vector<gr_complex> _val)
38{
39 return pmt::init_c32vector(_val.size(), _val);
40}
41
42template <class myType>
44{
45public:
46 pycallback_object(std::string name,
47 std::string functionbase,
48 std::string units,
49 std::string desc,
50 myType min,
51 myType max,
52 myType deflt,
53 DisplayType dtype)
54 : d_callback(NULL),
55 d_functionbase(functionbase),
56 d_units(units),
57 d_desc(desc),
58 d_min(min),
59 d_max(max),
60 d_deflt(deflt),
61 d_dtype(dtype),
62 d_name(name),
64 {
65 d_callback = NULL;
66 setup_rpc();
67 }
68
69 void add_rpc_variable(rpcbasic_sptr s) { d_rpc_vars.push_back(s); }
70
71 myType get()
72 {
73 myType rVal = d_deflt;
74 if (d_callback == NULL) {
75 std::cerr
76 << "WARNING: pycallback_object get() called without py callback set!"
77 << std::endl;
78 return rVal;
79 } else {
80 // obtain PyGIL
81 PyGILState_STATE state = PyGILState_Ensure();
82
83 PyObject* func;
84 // PyObject *arglist;
85 PyObject* result;
86
87 func = (PyObject*)d_callback; // Get Python function
88 // arglist = Py_BuildValue(""); // Build argument list
89 result = PyEval_CallObject(func, NULL); // Call Python
90 // result = PyEval_CallObject(func,arglist); // Call Python
91 // Py_DECREF(arglist); // Trash arglist
92 if (result) { // If no errors, return double
93 rVal = pyCast(result);
94 }
95 Py_XDECREF(result);
96
97 // release PyGIL
98 PyGILState_Release(state);
99 return rVal;
100 }
101 }
102
103 void set_callback(PyObject* cb) { d_callback = cb; }
104
106 {
107#ifdef GR_CTRLPORT
110 (boost::format("%s%d") % d_name % d_id).str(),
111 d_functionbase.c_str(),
112 this,
117 d_units.c_str(),
118 d_desc.c_str(),
120 d_dtype)));
121#endif /* GR_CTRLPORT */
122 }
123
124private:
125 PyObject* d_callback;
126 std::string d_functionbase, d_units, d_desc;
127 myType d_min, d_max, d_deflt;
128 DisplayType d_dtype;
129
130 /* This is a fall-through converter in case someone tries to call pyCast on an
131 * object type for which there isn't a template specialization (located below
132 * this class) function. This function should never get called, and it is
133 * unknown if changing the return type from myType to 'void' will break
134 * something. */
135 myType pyCast(PyObject* obj)
136 {
137 std::cerr << "TYPE NOT IMPLEMENTED!" << std::endl;
138 assert(0);
139 // the following is to make compilers happy only.
140 myType dummy;
141 return (dummy);
142 };
143
144 std::vector<rpcbasic_sptr> d_rpc_vars; // container for all RPC variables
145 std::string d_name;
146 int d_id;
147};
148
149
150// template specialization conversion functions
151// get data out of the PyObject and into the real world
152template <>
153std::string pycallback_object<std::string>::pyCast(PyObject* obj)
154{
155#if PY_MAJOR_VERSION >= 3
156 return std::string(PyUnicode_AsUTF8(obj));
157#else
158 return std::string(PyString_AsString(obj));
159#endif
160}
161
162template <>
163double pycallback_object<double>::pyCast(PyObject* obj)
164{
165 return PyFloat_AsDouble(obj);
166}
167
168template <>
169float pycallback_object<float>::pyCast(PyObject* obj)
170{
171 return (float)PyFloat_AsDouble(obj);
172}
173
174template <>
175int pycallback_object<int>::pyCast(PyObject* obj)
176{
177 return PyInt_AsLong(obj);
178}
179
180template <>
181std::vector<float> pycallback_object<std::vector<float>>::pyCast(PyObject* obj)
182{
183 int size = PyObject_Size(obj);
184 std::vector<float> rval(size);
185 for (int i = 0; i < size; i++) {
186 rval[i] = (float)PyFloat_AsDouble(PyList_GetItem(obj, i));
187 }
188 return rval;
189}
190
191template <>
192std::vector<gr_complex> pycallback_object<std::vector<gr_complex>>::pyCast(PyObject* obj)
193{
194 int size = PyObject_Size(obj);
195 std::vector<gr_complex> rval(size);
196 for (int i = 0; i < size; i++) {
197 rval[i] = gr_complex((float)PyComplex_RealAsDouble(PyList_GetItem(obj, i)),
198 (float)PyComplex_ImagAsDouble(PyList_GetItem(obj, i)));
199 }
200 return rval;
201}
202// TODO: add more template specializations as needed!
Definition: pycallback_object.h:24
static pmt::pmt_t make(myType _val)
Definition: pycallback_object.h:26
Definition: pycallback_object.h:44
pycallback_object(std::string name, std::string functionbase, std::string units, std::string desc, myType min, myType max, myType deflt, DisplayType dtype)
Definition: pycallback_object.h:46
void set_callback(PyObject *cb)
Definition: pycallback_object.h:103
void add_rpc_variable(rpcbasic_sptr s)
Definition: pycallback_object.h:69
void setup_rpc()
Definition: pycallback_object.h:105
myType get()
Definition: pycallback_object.h:71
Registers a 'get' function to get a parameter over ControlPort.
Definition: rpcregisterhelpers.h:1107
std::complex< float > gr_complex
Definition: gr_complex.h:15
float min(float a, float b)
PMT_API pmt_t init_f32vector(size_t k, const float *data)
PMT_API pmt_t init_c32vector(size_t k, const std::complex< float > *data)
static pmt_t mp(const std::string &s)
Make pmt symbol.
Definition: pmt_sugar.h:24
std::shared_ptr< pmt_base > pmt_t
typedef for shared pointer (transparent reference counting).
Definition: pmt.h:84
int pycallback_object_count
Definition: pycallback_object.h:19
pyport_t
Definition: pycallback_object.h:17
@ PYPORT_FLOAT
Definition: pycallback_object.h:17
@ PYPORT_STRING
Definition: pycallback_object.h:17
@ RPC_PRIVLVL_MIN
Definition: rpccallbackregister_base.h:34
uint32_t DisplayType
Definition: rpccallbackregister_base.h:17