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 
39 typedef PyObject* PyObject_Repr(PyObject *);
40 typedef const char* PyUnicode_AsUTF8(PyObject *unicode);
41 
42 // holder to ensure we release the GIL even in error conditions
43 class GilHolder {
44     PyGILState_STATE _gilState;
45     PyGILState_Release* _release;
46 public:
GilHolder(PyGILState_Ensure * acquire,PyGILState_Release * release)47     GilHolder(PyGILState_Ensure* acquire, PyGILState_Release* release) {
48         _gilState = acquire();
49         _release = release;
50     }
51 
~GilHolder()52     ~GilHolder() {
53         _release(_gilState);
54     }
55 };
56 
57 #ifdef _WIN32
58 
59 #define PRINT(msg) {std::cout << msg << std::endl << std::flush;}
60 
61 #define DEFINE_PROC_NO_CHECK(func, funcType, funcNameStr, errorCode) \
62                     funcType func=reinterpret_cast<funcType>(GetProcAddress(module, funcNameStr));
63 
64 #define DEFINE_PROC(func, funcType, funcNameStr, errorCode) \
65                     DEFINE_PROC_NO_CHECK(func, funcType, funcNameStr, errorCode); \
66                     if(func == nullptr){std::cout << funcNameStr << " not found." << std::endl << std::flush; return errorCode;};
67 
68 #else // LINUX -----------------------------------------------------------------
69 
70 #define PRINT(msg) {printf(msg); printf("\n");}
71 
72 #define CHECK_NULL(ptr, msg, errorCode) if(ptr == nullptr){printf(msg); return errorCode;}
73 
74 #define DEFINE_PROC_NO_CHECK(func, funcType, funcNameStr, errorCode) \
75                     funcType func; *(void**)(&func) = dlsym(module, funcNameStr);
76 
77 #define DEFINE_PROC(func, funcType, funcNameStr, errorCode) \
78                     DEFINE_PROC_NO_CHECK(func, funcType, funcNameStr, errorCode); \
79                     if(func == nullptr){printf(funcNameStr); printf(" not found.\n"); return errorCode;};
80 
81 #endif //_WIN32
82 
83 #endif //_PY_UTILS_HPP_