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