not sure, if it answers your question, but here's the generated code for cv2.circle():
(if you built your cv2 locally, you will find it opencv/build/modules/python_bindings_generator/pyopencv_generated_funcs.h)
actually, every c++ opencv call is wrapped in this ERRWRAP2
macro, so the answer is probably: yes !
static PyObject* pyopencv_cv_circle(PyObject* , PyObject* args, PyObject* kw)
{
using namespace cv;
{
PyObject* pyobj_img = NULL;
Mat img;
PyObject* pyobj_center = NULL;
Point center;
int radius=0;
PyObject* pyobj_color = NULL;
Scalar color;
int thickness=1;
int lineType=LINE_8;
int shift=0;
const char* keywords[] = { "img", "center", "radius", "color", "thickness", "lineType", "shift", NULL };
if( PyArg_ParseTupleAndKeywords(args, kw, "OOiO|iii:circle", (char**)keywords, &pyobj_img, &pyobj_center, &radius, &pyobj_color, &thickness, &lineType, &shift) &&
pyopencv_to(pyobj_img, img, ArgInfo("img", 1)) &&
pyopencv_to(pyobj_center, center, ArgInfo("center", 0)) &&
pyopencv_to(pyobj_color, color, ArgInfo("color", 0)) )
{
ERRWRAP2(cv::circle(img, center, radius, color, thickness, lineType, shift));
return pyopencv_from(img);
}
}
PyErr_Clear();
{
PyObject* pyobj_img = NULL;
UMat img;
PyObject* pyobj_center = NULL;
Point center;
int radius=0;
PyObject* pyobj_color = NULL;
Scalar color;
int thickness=1;
int lineType=LINE_8;
int shift=0;
const char* keywords[] = { "img", "center", "radius", "color", "thickness", "lineType", "shift", NULL };
if( PyArg_ParseTupleAndKeywords(args, kw, "OOiO|iii:circle", (char**)keywords, &pyobj_img, &pyobj_center, &radius, &pyobj_color, &thickness, &lineType, &shift) &&
pyopencv_to(pyobj_img, img, ArgInfo("img", 1)) &&
pyopencv_to(pyobj_center, center, ArgInfo("center", 0)) &&
pyopencv_to(pyobj_color, color, ArgInfo("color", 0)) )
{
ERRWRAP2(cv::circle(img, center, radius, color, thickness, lineType, shift));
return pyopencv_from(img);
}
}
return NULL;
}
why do you think, it even does release the GIL, ever ?
(it never happens, to my knowledge)
(if so, it would look like this , no ? )
The
ERRWRAP2
macro prepends a PyAllowThreads guard object to every function call that releases the GIL with a call to PyEval_SaveThread when constructed and acquires it when it is destructed. ThePy_BEGIN_ALLOW_THREADS
macro that you linked to expands to aPyEval_SaveThread
call (and more) so they are equivalent.The preferred way for GIL release in C++ is to use a guard class like PyAllowThreads for better exception handling, while C programs tend to use the
Py_BEGIN_ALLOW_THREADS
macro.oh, thanks, i didn't knew that !
btw, the
CV_WRAP
macro is for class member functions, "free" functions need aCV_EXPORTS_W
instead, and it has to happen in the interface header, not in the cpp implementation file