1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
#ifndef CV2_UTIL_HPP
#define CV2_UTIL_HPP
#include "cv2.hpp"
#include "opencv2/core.hpp"
#include "opencv2/core/utils/tls.hpp"
#include <vector>
#include <string>
//======================================================================================================================
bool isPythonBindingsDebugEnabled();
void emit_failmsg(PyObject * exc, const char *msg);
int failmsg(const char *fmt, ...);
PyObject* failmsgp(const char *fmt, ...);
//======================================================================================================================
class PyAllowThreads
{
public:
PyAllowThreads() : _state(PyEval_SaveThread()) {}
~PyAllowThreads()
{
PyEval_RestoreThread(_state);
}
private:
PyThreadState* _state;
};
class PyEnsureGIL
{
public:
PyEnsureGIL() : _state(PyGILState_Ensure()) {}
~PyEnsureGIL()
{
PyGILState_Release(_state);
}
private:
PyGILState_STATE _state;
};
/**
* Light weight RAII wrapper for `PyObject*` owning references.
* In comparison to C++11 `std::unique_ptr` with custom deleter, it provides
* implicit conversion functions that might be useful to initialize it with
* Python functions those returns owning references through the `PyObject**`
* e.g. `PyErr_Fetch` or directly pass it to functions those want to borrow
* reference to object (doesn't extend object lifetime) e.g. `PyObject_Str`.
*/
class PySafeObject
{
public:
PySafeObject() : obj_(NULL) {}
explicit PySafeObject(PyObject* obj) : obj_(obj) {}
~PySafeObject()
{
Py_CLEAR(obj_);
}
operator PyObject*()
{
return obj_;
}
operator PyObject**()
{
return &obj_;
}
operator bool() {
return obj_ != nullptr;
}
PyObject* release()
{
PyObject* obj = obj_;
obj_ = NULL;
return obj;
}
private:
PyObject* obj_;
// Explicitly disable copy operations
PySafeObject(const PySafeObject*); // = delete
PySafeObject& operator=(const PySafeObject&); // = delete
};
//======================================================================================================================
extern PyObject* opencv_error;
void pyRaiseCVException(const cv::Exception &e);
#define ERRWRAP2(expr) \
try \
{ \
PyAllowThreads allowThreads; \
expr; \
} \
catch (const cv::Exception &e) \
{ \
pyRaiseCVException(e); \
return 0; \
} \
catch (const std::exception &e) \
{ \
PyErr_SetString(opencv_error, e.what()); \
return 0; \
} \
catch (...) \
{ \
PyErr_SetString(opencv_error, "Unknown C++ exception from OpenCV code"); \
return 0; \
}
//======================================================================================================================
extern cv::TLSData<std::vector<std::string> > conversionErrorsTLS;
inline void pyPrepareArgumentConversionErrorsStorage(std::size_t size)
{
std::vector<std::string>& conversionErrors = conversionErrorsTLS.getRef();
conversionErrors.clear();
conversionErrors.reserve(size);
}
void pyRaiseCVOverloadException(const std::string& functionName);
void pyPopulateArgumentConversionErrors();
//======================================================================================================================
PyObject *pycvRedirectError(PyObject*, PyObject *args, PyObject *kw);
#endif // CV2_UTIL_HPP
|