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