py_opcua_subscriptionclient.cpp
Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 #include "py_opcua_subscriptionclient.h"
00012 
00013 static std::string parse_python_exception()
00014 {
00015   PyObject * type_ptr = NULL, *value_ptr = NULL, *traceback_ptr = NULL;
00016   // Fetch the exception info from the Python C API
00017   PyErr_Fetch(&type_ptr, &value_ptr, &traceback_ptr);
00018   // Fallback error
00019   std::string ret("Unfetchable Python error");
00020 
00021   // If the fetch got a type pointer, parse the type into the exception string
00022   if (type_ptr != NULL)
00023     {
00024       handle<> h_type(type_ptr);
00025       str type_pstr(h_type);
00026       // Extract the string from the boost::python object
00027       extract<std::string> e_type_pstr(type_pstr);
00028 
00029       // If a valid string extraction is available, use it
00030       // otherwise use fallback
00031       if (e_type_pstr.check())
00032         { ret = e_type_pstr(); }
00033 
00034       else
00035         { ret = "Unknown exception type"; }
00036     }
00037 
00038   // Do the same for the exception value (the stringification of the exception)
00039   if (value_ptr != NULL)
00040     {
00041       handle<> h_val(value_ptr);
00042       str a(h_val);
00043       extract<std::string> returned(a);
00044 
00045       if (returned.check())
00046         { ret += ": " + returned(); }
00047 
00048       else
00049         { ret += std::string(": Unparseable Python error: "); }
00050     }
00051 
00052   // Parse lines from the traceback using the Python traceback module
00053   if (traceback_ptr != NULL)
00054     {
00055       handle<> h_tb(traceback_ptr);
00056       // Load the traceback module and the format_tb function
00057       object tb(import("traceback"));
00058       object fmt_tb(tb.attr("format_tb"));
00059       // Call format_tb to get a list of traceback strings
00060       object tb_list(fmt_tb(h_tb));
00061       // Join the traceback strings into a single string
00062       object tb_str(str("\n").join(tb_list));
00063       // Extract the string, check the extraction, and fallback in necessary
00064       extract<std::string> returned(tb_str);
00065 
00066       if (returned.check())
00067         { ret += ": " + returned(); }
00068 
00069       else
00070         { ret += std::string(": Unparseable Python traceback"); }
00071     }
00072 
00073   return ret;
00074 }
00075 
00076 PySubscriptionHandler::PySubscriptionHandler(PyObject * p)
00077   : self(p)
00078 {}
00079 
00080 void PySubscriptionHandler::DataChange(uint32_t handle, const Node & node, const Variant & val, AttributeId attribute)
00081 {
00082   PyGILState_STATE state = PyGILState_Ensure();
00083 
00084   try
00085     {
00086       call_method<void>(self, "data_change", handle, node, val , attribute);
00087     }
00088 
00089   catch (const error_already_set & ex)
00090     {
00091       std::string perror_str = parse_python_exception();
00092       std::cout << "Error in 'data_change' method handler: " << perror_str << std::endl;
00093     }
00094 
00095   PyGILState_Release(state);
00096 }
00097 
00098 void PySubscriptionHandler::Event(uint32_t handle, const OpcUa::Event & event)
00099 {
00100   PyGILState_STATE state = PyGILState_Ensure();
00101 
00102   try
00103     {
00104       call_method<void>(self, "event", handle, event);
00105     }
00106   catch (const error_already_set & ex)
00107     {
00108       std::string perror_str = parse_python_exception();
00109       std::cout << "Error in 'event' method handler: " << perror_str << std::endl;
00110     }
00111 
00112   PyGILState_Release(state);
00113 }
00114 
00115 void PySubscriptionHandler::StatusChange(StatusCode status)
00116 {
00117   PyGILState_STATE state = PyGILState_Ensure();
00118 
00119   try
00120     {
00121       call_method<void>(self, "status_change", status);
00122     }
00123 
00124   catch (const error_already_set & ex)
00125     {
00126       std::string perror_str = parse_python_exception();
00127       std::cout << "Error in 'status_change' method handler: " << perror_str << std::endl;
00128     }
00129 
00130   PyGILState_Release(state);
00131 }
00132 
00133 void PySubscriptionHandler::DefaultDataChange(const SubscriptionHandler & self_, uint32_t handle, const Node & node, const object & val, uint32_t attribute)
00134 {
00135   std::cout << "'data_change' virtual in this context" << std::endl;
00136 }
00137 
00138 void PySubscriptionHandler::DefaultEvent(const SubscriptionHandler & self_, uint32_t handle, const OpcUa::Event & event)
00139 {
00140   std::cout << "'event' virtual in this context" << std::endl;
00141 }
00142 
00143 void PySubscriptionHandler::DefaultStatusChange(const SubscriptionHandler & self_, StatusCode status)
00144 {
00145   std::cout << "'status_change' virtual in this context" << std::endl;
00146 }
00147 
00148 


ros_opcua_impl_freeopcua
Author(s): Denis Štogl
autogenerated on Sat Jun 8 2019 18:24:56