msg_lookup.cpp
Go to the documentation of this file.
1 
31 #include "Python.h"
32 
33 namespace rosserial_server
34 {
35 
36 const MsgInfo lookupMessage(const std::string& message_type, const std::string submodule)
37 {
38  // Lazy-initialize the embedded Python interpreter. Avoid calling the corresponding
39  // finalize method due to issues with importing cyaml in the second instance. The
40  // total memory cost of having this in-process is only about 5-6MB.
41  Py_Initialize();
42 
43  MsgInfo msginfo;
44  size_t slash_pos = message_type.find('/');
45  if (slash_pos == std::string::npos)
46  {
47  throw std::runtime_error("Passed message type string does not include a slash character.");
48  }
49  std::string module_name = message_type.substr(0, slash_pos);
50  std::string class_name = message_type.substr(slash_pos + 1, std::string::npos);
51 
52  PyObject* module = PyImport_ImportModule((module_name + "." + submodule).c_str());
53  if (!module)
54  {
55  throw std::runtime_error("Unable to import message module " + module_name + ".");
56  }
57  PyObject* msg_class = PyObject_GetAttrString(module, class_name.c_str());
58  if (!msg_class)
59  {
60  throw std::runtime_error("Unable to find message class " + class_name +
61  " in module " + module_name + ".");
62  }
63  Py_XDECREF(module);
64 
65  PyObject* full_text = PyObject_GetAttrString(msg_class, "_full_text");
66  PyObject* md5sum = PyObject_GetAttrString(msg_class, "_md5sum");
67  if (!md5sum)
68  {
69  throw std::runtime_error("Class for message " + message_type + " did not contain" +
70  "expected _md5sum attribute.");
71  }
72  Py_XDECREF(msg_class);
73 
74 #if PY_VERSION_HEX > 0x03000000
75  if (full_text)
76  {
77  msginfo.full_text.assign(PyUnicode_AsUTF8(full_text));
78  }
79  msginfo.md5sum.assign(PyUnicode_AsUTF8(md5sum));
80 #else
81  if (full_text)
82  {
83  msginfo.full_text.assign(PyString_AsString(full_text));
84  }
85  msginfo.md5sum.assign(PyString_AsString(md5sum));
86 #endif
87 
88  // See https://github.com/ros/ros_comm/issues/344
89  // and https://github.com/ros/gencpp/pull/14
90  // Valid full_text returned, but it is empty, so insert single line
91  if (full_text && msginfo.full_text.empty())
92  {
93  msginfo.full_text = "\n";
94  }
95 
96  Py_XDECREF(full_text);
97  Py_XDECREF(md5sum);
98 
99  return msginfo;
100 }
101 
102 } // namespace rosserial_server
rosserial_server::MsgInfo::md5sum
std::string md5sum
Definition: msg_lookup.h:38
md5sum
const char * md5sum()
rosserial_server::MsgInfo
Definition: msg_lookup.h:36
msg_lookup.h
PyUnicode_AsUTF8
#define PyUnicode_AsUTF8
rosserial_server::lookupMessage
const MsgInfo lookupMessage(const std::string &message_type, const std::string submodule="msg")
Definition: msg_lookup.cpp:36
rosserial_server::MsgInfo::full_text
std::string full_text
Definition: msg_lookup.h:39
rosserial_server
Definition: async_read_buffer.h:48


rosserial_server
Author(s): Mike Purvis
autogenerated on Wed Mar 2 2022 00:58:14