py_utils.hpp
 1  #ifndef _PY_UTILS_HPP_
 2  #define _PY_UTILS_HPP_
 3  
 4  typedef int (Py_IsInitialized)();
 5  typedef PyInterpreterState* (PyInterpreterState_Head)();
 6  typedef enum { PyGILState_LOCKED, PyGILState_UNLOCKED } PyGILState_STATE;
 7  typedef PyGILState_STATE(PyGILState_Ensure)();
 8  typedef void (PyGILState_Release)(PyGILState_STATE);
 9  typedef int (PyRun_SimpleString)(const char *command);
10  typedef PyThreadState* (PyInterpreterState_ThreadHead)(PyInterpreterState* interp);
11  typedef PyThreadState* (PyThreadState_Next)(PyThreadState *tstate);
12  typedef PyThreadState* (PyThreadState_Swap)(PyThreadState *tstate);
13  typedef PyThreadState* (_PyThreadState_UncheckedGet)();
14  typedef PyObject* (PyObject_CallFunctionObjArgs)(PyObject *callable, ...);    // call w/ varargs, last arg should be nullptr
15  typedef PyObject* (PyInt_FromLong)(long);
16  typedef PyObject* (PyErr_Occurred)();
17  typedef void (PyErr_Fetch)(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback);
18  typedef void (PyErr_Restore)(PyObject *type, PyObject *value, PyObject *traceback);
19  typedef PyObject* (PyImport_ImportModule) (const char *name);
20  typedef PyObject* (PyImport_ImportModuleNoBlock) (const char *name);
21  typedef PyObject* (PyObject_GetAttrString)(PyObject *o, const char *attr_name);
22  typedef PyObject* (PyObject_HasAttrString)(PyObject *o, const char *attr_name);
23  typedef void* (PyThread_get_key_value)(int);
24  typedef int (PyThread_set_key_value)(int, void*);
25  typedef void (PyThread_delete_key_value)(int);
26  typedef int (PyObject_Not) (PyObject *o);
27  typedef PyObject* (PyDict_New)();
28  typedef PyObject* (PyUnicode_InternFromString)(const char *u);
29  typedef PyObject * (_PyObject_FastCallDict)(
30      PyObject *callable, PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs);
31  typedef int (PyTraceBack_Here)(PyFrameObject *frame);
32  
33  typedef PyObject* PyTuple_New(Py_ssize_t len);
34  typedef PyObject* PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs);
35  
36  typedef void (PyEval_SetTrace)(Py_tracefunc, PyObject *);
37  typedef int (*Py_tracefunc)(PyObject *, PyFrameObject *frame, int, PyObject *);
38  typedef int (_PyEval_SetTrace)(PyThreadState *tstate, Py_tracefunc func, PyObject *arg);
39  
40  typedef PyObject* PyObject_Repr(PyObject *);
41  typedef const char* PyUnicode_AsUTF8(PyObject *unicode);
42  
43  // holder to ensure we release the GIL even in error conditions
44  class GilHolder {
45      PyGILState_STATE _gilState;
46      PyGILState_Release* _release;
47  public:
48      GilHolder(PyGILState_Ensure* acquire, PyGILState_Release* release) {
49          _gilState = acquire();
50          _release = release;
51      }
52  
53      ~GilHolder() {
54          _release(_gilState);
55      }
56  };
57  
58  #ifdef _WIN32
59  
60  #define PRINT(msg) {std::cout << msg << std::endl << std::flush;}
61  
62  #define DEFINE_PROC_NO_CHECK(func, funcType, funcNameStr, errorCode) \
63                      funcType func=reinterpret_cast<funcType>(GetProcAddress(module, funcNameStr));
64  
65  #define DEFINE_PROC(func, funcType, funcNameStr, errorCode) \
66                      DEFINE_PROC_NO_CHECK(func, funcType, funcNameStr, errorCode); \
67                      if(func == nullptr){std::cout << funcNameStr << " not found." << std::endl << std::flush; return errorCode;};
68  
69  #else // LINUX -----------------------------------------------------------------
70  
71  #define PRINT(msg) {printf(msg); printf("\n");}
72  
73  #define CHECK_NULL(ptr, msg, errorCode) if(ptr == nullptr){printf(msg); return errorCode;}
74  
75  #define DEFINE_PROC_NO_CHECK(func, funcType, funcNameStr, errorCode) \
76                      funcType func; *(void**)(&func) = dlsym(module, funcNameStr);
77  
78  #define DEFINE_PROC(func, funcType, funcNameStr, errorCode) \
79                      DEFINE_PROC_NO_CHECK(func, funcType, funcNameStr, errorCode); \
80                      if(func == nullptr){printf(funcNameStr); printf(" not found.\n"); return errorCode;};
81  
82  #endif //_WIN32
83  
84  #endif //_PY_UTILS_HPP_