1 #pragma once
2 
3 #ifdef WIN32
4 #	define MS_NO_COREDLL 1
5 #else
6 #	pragma GCC diagnostic ignored "-Wwrite-strings"
7 #endif
8 
9 #ifdef WITH_THREAD
10 #    undefine WITH_THREAD
11 #endif
12 #include <Python.h>
13 #include <structmember.h>
14 #include <frameobject.h>
15 #include "../../main/Helper.h"
16 
17 #if PY_VERSION_HEX >= 0x030800f0
18 static inline void
py3__Py_DECREF(const char * filename,int lineno,PyObject * op)19 py3__Py_DECREF(const char *filename, int lineno, PyObject *op)
20 {
21 	(void)filename; /* may be unused, shut up -Wunused-parameter */
22 	(void)lineno; /* may be unused, shut up -Wunused-parameter */
23 	_Py_DEC_REFTOTAL;
24 	if (--op->ob_refcnt != 0)
25 	{
26 #ifdef Py_REF_DEBUG
27 	if (op->ob_refcnt < 0)
28 	{
29 		_Py_NegativeRefcount(filename, lineno, op);
30 	}
31 #endif
32 	}
33 	else
34 	{
35 		_Py_Dealloc(op);
36 	}
37 }
38 
39 #undef Py_DECREF
40 #define Py_DECREF(op) py3__Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op))
41 
42 static inline void
py3__Py_XDECREF(PyObject * op)43 py3__Py_XDECREF(PyObject *op)
44 {
45 	if (op != NULL)
46 	{
47 		Py_DECREF(op);
48 	}
49 }
50 
51 #undef Py_XDECREF
52 #define Py_XDECREF(op) py3__Py_XDECREF(_PyObject_CAST(op))
53 #endif
54 
55 namespace Plugins {
56 
57 #ifdef WIN32
58 #	define PYTHON_CALL __cdecl*
59 #	define RESOLVE_SYMBOL GetProcAddress
60 #else
61 #	include <dlfcn.h>
62 #	define PYTHON_CALL *
63 #	define RESOLVE_SYMBOL dlsym
64 #endif
65 
66 #define COMMA ,
67 #define DECLARE_PYTHON_SYMBOL(type, symbol, params)	typedef type (PYTHON_CALL symbol##_t)(params); symbol##_t  symbol
68 #define RESOLVE_PYTHON_SYMBOL(symbol)  symbol = (symbol##_t)RESOLVE_SYMBOL(shared_lib_, #symbol)
69 
70 	struct SharedLibraryProxy
71 	{
72 #ifdef WIN32
73 		HINSTANCE shared_lib_;
74 #else
75 		void* shared_lib_;
76 #endif
77 
78 		// Shared library interface begin.
79 		DECLARE_PYTHON_SYMBOL(const char*, Py_GetVersion, );
80 		DECLARE_PYTHON_SYMBOL(int, Py_IsInitialized, );
81 		DECLARE_PYTHON_SYMBOL(void, Py_Initialize, );
82 		DECLARE_PYTHON_SYMBOL(void, Py_Finalize, );
83 		DECLARE_PYTHON_SYMBOL(PyThreadState*, Py_NewInterpreter, );
84 		DECLARE_PYTHON_SYMBOL(void, Py_EndInterpreter, PyThreadState*);
85 		DECLARE_PYTHON_SYMBOL(wchar_t*, Py_GetPath, );
86 		DECLARE_PYTHON_SYMBOL(void, Py_SetPath, const wchar_t*);
87 		DECLARE_PYTHON_SYMBOL(void, PySys_SetPath, const wchar_t*);
88 		DECLARE_PYTHON_SYMBOL(void, Py_SetProgramName, wchar_t*);
89 		DECLARE_PYTHON_SYMBOL(wchar_t*, Py_GetProgramFullPath, );
90 		DECLARE_PYTHON_SYMBOL(int, PyImport_AppendInittab, const char* COMMA PyObject* (*initfunc)(void));
91 		DECLARE_PYTHON_SYMBOL(int, PyType_Ready, PyTypeObject*);
92 		DECLARE_PYTHON_SYMBOL(int, PyCallable_Check, PyObject*);
93 		DECLARE_PYTHON_SYMBOL(PyObject*, PyObject_GetAttrString, PyObject* pObj COMMA const char*);
94 		DECLARE_PYTHON_SYMBOL(int, PyObject_HasAttrString, PyObject* COMMA const char *);
95 		DECLARE_PYTHON_SYMBOL(const char*, PyBytes_AsString, PyObject*);
96 		DECLARE_PYTHON_SYMBOL(Py_ssize_t, PyBytes_Size, PyObject*);
97 		DECLARE_PYTHON_SYMBOL(PyObject*, PyUnicode_AsASCIIString, PyObject*);
98 		DECLARE_PYTHON_SYMBOL(PyObject*, PyUnicode_FromString, const char*);
99 		DECLARE_PYTHON_SYMBOL(wchar_t*, PyUnicode_AsWideCharString, PyObject* COMMA Py_ssize_t*);
100 		DECLARE_PYTHON_SYMBOL(const char*, PyUnicode_AsUTF8, PyObject*);
101 		DECLARE_PYTHON_SYMBOL(char*, PyByteArray_AsString, PyObject*);
102 		DECLARE_PYTHON_SYMBOL(PyObject*, PyUnicode_FromKindAndData, int COMMA const void* COMMA Py_ssize_t);
103 		DECLARE_PYTHON_SYMBOL(PyObject*, PyLong_FromLong, long);
104 		DECLARE_PYTHON_SYMBOL(PY_LONG_LONG, PyLong_AsLongLong, PyObject*);
105 		DECLARE_PYTHON_SYMBOL(PyObject*, PyModule_GetDict, PyObject*);
106 		DECLARE_PYTHON_SYMBOL(PyObject*, PyDict_New, );
107 		DECLARE_PYTHON_SYMBOL(void, PyDict_Clear, PyObject *);
108 		DECLARE_PYTHON_SYMBOL(Py_ssize_t, PyDict_Size, PyObject*);
109 		DECLARE_PYTHON_SYMBOL(PyObject *, PyDict_GetItem, PyObject* COMMA PyObject*);
110 		DECLARE_PYTHON_SYMBOL(PyObject *, PyDict_GetItemString, PyObject* COMMA const char*);
111 		DECLARE_PYTHON_SYMBOL(int, PyDict_SetItemString, PyObject* COMMA const char* COMMA PyObject*);
112 		DECLARE_PYTHON_SYMBOL(int, PyDict_SetItem, PyObject* COMMA PyObject* COMMA PyObject*);
113 		DECLARE_PYTHON_SYMBOL(int, PyDict_DelItem, PyObject* COMMA PyObject*);
114 		DECLARE_PYTHON_SYMBOL(int, PyDict_Next, PyObject* COMMA Py_ssize_t* COMMA PyObject** COMMA PyObject**);
115 		DECLARE_PYTHON_SYMBOL(PyObject*, PyDict_Items, PyObject*);
116 		DECLARE_PYTHON_SYMBOL(PyObject*, PyList_New, Py_ssize_t);
117 		DECLARE_PYTHON_SYMBOL(Py_ssize_t, PyList_Size, PyObject*);
118 		DECLARE_PYTHON_SYMBOL(Py_ssize_t, PyTuple_Size, PyObject*);
119 		DECLARE_PYTHON_SYMBOL(int, PyList_Append, PyObject* COMMA PyObject*);
120 		DECLARE_PYTHON_SYMBOL(PyObject*, PyList_GetItem, PyObject* COMMA Py_ssize_t);
121 		DECLARE_PYTHON_SYMBOL(PyObject*, PyTuple_GetItem, PyObject* COMMA Py_ssize_t);
122 		DECLARE_PYTHON_SYMBOL(int, PyList_SetItem, PyObject* COMMA Py_ssize_t COMMA PyObject*);
123 		DECLARE_PYTHON_SYMBOL(void*, PyModule_GetState, PyObject*);
124 		DECLARE_PYTHON_SYMBOL(PyObject*, PyState_FindModule, struct PyModuleDef*);
125 		DECLARE_PYTHON_SYMBOL(void, PyErr_Clear, );
126 		DECLARE_PYTHON_SYMBOL(void, PyErr_Fetch, PyObject** COMMA PyObject** COMMA PyObject**);
127 		DECLARE_PYTHON_SYMBOL(PyObject*, PyImport_ImportModule, const char*);
128 		DECLARE_PYTHON_SYMBOL(PyObject*, PyObject_CallObject, PyObject* COMMA PyObject*);
129 		DECLARE_PYTHON_SYMBOL(int, PyFrame_GetLineNumber, PyFrameObject*);
130 		DECLARE_PYTHON_SYMBOL(void, PyEval_InitThreads, );
131 		DECLARE_PYTHON_SYMBOL(int, PyEval_ThreadsInitialized, );
132 		DECLARE_PYTHON_SYMBOL(PyThreadState*, PyThreadState_Get, );
133 		DECLARE_PYTHON_SYMBOL(PyThreadState*, PyEval_SaveThread, void);
134 		DECLARE_PYTHON_SYMBOL(void, PyEval_RestoreThread, PyThreadState*);
135 		DECLARE_PYTHON_SYMBOL(void, PyEval_ReleaseLock, );
136 		DECLARE_PYTHON_SYMBOL(PyThreadState*, PyThreadState_Swap, PyThreadState*);
137 		DECLARE_PYTHON_SYMBOL(int, PyGILState_Check, );
138 		DECLARE_PYTHON_SYMBOL(void, _Py_NegativeRefcount, const char* COMMA int COMMA PyObject*);
139 		DECLARE_PYTHON_SYMBOL(PyObject*, _PyObject_New, PyTypeObject*);
140 #ifdef _DEBUG
141 		DECLARE_PYTHON_SYMBOL(PyObject*, PyModule_Create2TraceRefs, struct PyModuleDef* COMMA int);
142 #else
143 		DECLARE_PYTHON_SYMBOL(PyObject*, PyModule_Create2, struct PyModuleDef* COMMA int);
144 #endif
145 		DECLARE_PYTHON_SYMBOL(int, PyModule_AddObject, PyObject* COMMA const char* COMMA PyObject*);
146 		DECLARE_PYTHON_SYMBOL(int, PyArg_ParseTuple, PyObject* COMMA const char* COMMA ...);
147 		DECLARE_PYTHON_SYMBOL(int, PyArg_ParseTupleAndKeywords, PyObject* COMMA PyObject* COMMA const char* COMMA char*[] COMMA ...);
148 		DECLARE_PYTHON_SYMBOL(PyObject*, PyUnicode_FromFormat, const char* COMMA ...);
149 		DECLARE_PYTHON_SYMBOL(PyObject*, Py_BuildValue, const char* COMMA ...);
150 		DECLARE_PYTHON_SYMBOL(void, PyMem_Free, void*);
151 		DECLARE_PYTHON_SYMBOL(PyObject*, PyBool_FromLong, long);
152         DECLARE_PYTHON_SYMBOL(int, PyRun_SimpleStringFlags, const char* COMMA PyCompilerFlags*);
153         DECLARE_PYTHON_SYMBOL(int, PyRun_SimpleFileExFlags, FILE* COMMA const char* COMMA int COMMA PyCompilerFlags*);
154 		DECLARE_PYTHON_SYMBOL(void*, PyCapsule_Import, const char *name COMMA int);
155 		DECLARE_PYTHON_SYMBOL(void*, PyType_GenericAlloc, const PyTypeObject * COMMA Py_ssize_t);
156 		DECLARE_PYTHON_SYMBOL(PyObject*, PyUnicode_DecodeUTF8, const char * COMMA Py_ssize_t COMMA const char *);
157 		DECLARE_PYTHON_SYMBOL(Py_ssize_t, PyUnicode_GetLength, PyObject*);
158 		DECLARE_PYTHON_SYMBOL(int, PyType_IsSubtype, PyTypeObject* COMMA PyTypeObject*);
159 		DECLARE_PYTHON_SYMBOL(Py_ssize_t, PyByteArray_Size, PyObject*);
160 		DECLARE_PYTHON_SYMBOL(PyObject*, PyErr_Occurred, );
161 		DECLARE_PYTHON_SYMBOL(long, PyLong_AsLong, PyObject*);
162 		DECLARE_PYTHON_SYMBOL(PyObject*, PyUnicode_AsUTF8String, PyObject*);
163 		DECLARE_PYTHON_SYMBOL(PyObject*, PyImport_AddModule, const char*);
164 		DECLARE_PYTHON_SYMBOL(void, PyEval_SetProfile, Py_tracefunc COMMA PyObject*);
165 		DECLARE_PYTHON_SYMBOL(void, PyEval_SetTrace, Py_tracefunc COMMA PyObject*);
166 		DECLARE_PYTHON_SYMBOL(PyObject*, PyObject_Str, PyObject*);
167 		DECLARE_PYTHON_SYMBOL(int, PyObject_IsTrue, PyObject*);
168 		DECLARE_PYTHON_SYMBOL(double, PyFloat_AsDouble, PyObject*);
169 		DECLARE_PYTHON_SYMBOL(PyObject*, PyObject_GetIter, PyObject*);
170 		DECLARE_PYTHON_SYMBOL(PyObject*, PyIter_Next, PyObject*);
171 
172 #ifdef _DEBUG
173 		// In a debug build dealloc is a function but for release builds its a macro
174 		DECLARE_PYTHON_SYMBOL(void, _Py_Dealloc, PyObject*);
175 #endif
176 		Py_ssize_t		_Py_RefTotal;
177 		PyObject		_Py_NoneStruct;
178 
SharedLibraryProxySharedLibraryProxy179 		SharedLibraryProxy() {
180 			shared_lib_ = 0;
181 			_Py_RefTotal = 0;
182 			if (!shared_lib_) {
183 #ifdef WIN32
184 #	ifdef _DEBUG
185 				if (!shared_lib_) shared_lib_ = LoadLibrary("python38_d.dll");
186 				if (!shared_lib_) shared_lib_ = LoadLibrary("python37_d.dll");
187 				if (!shared_lib_) shared_lib_ = LoadLibrary("python36_d.dll");
188 				if (!shared_lib_) shared_lib_ = LoadLibrary("python35_d.dll");
189 				if (!shared_lib_) shared_lib_ = LoadLibrary("python34_d.dll");
190 #	else
191 				if (!shared_lib_) shared_lib_ = LoadLibrary("python38.dll");
192 				if (!shared_lib_) shared_lib_ = LoadLibrary("python37.dll");
193 				if (!shared_lib_) shared_lib_ = LoadLibrary("python36.dll");
194 				if (!shared_lib_) shared_lib_ = LoadLibrary("python35.dll");
195 				if (!shared_lib_) shared_lib_ = LoadLibrary("python34.dll");
196 #	endif
197 #else
198 				if (!shared_lib_) FindLibrary("python3.8", true);
199 				if (!shared_lib_) FindLibrary("python3.7", true);
200 				if (!shared_lib_) FindLibrary("python3.6", true);
201 				if (!shared_lib_) FindLibrary("python3.5", true);
202 				if (!shared_lib_) FindLibrary("python3.4", true);
203 #ifdef __FreeBSD__
204 				if (!shared_lib_) FindLibrary("python3.7m", true);
205 				if (!shared_lib_) FindLibrary("python3.6m", true);
206 				if (!shared_lib_) FindLibrary("python3.5m", true);
207 				if (!shared_lib_) FindLibrary("python3.4m", true);
208 #endif /* FreeBSD */
209 #endif
210 				if (shared_lib_)
211 				{
212 					RESOLVE_PYTHON_SYMBOL(Py_GetVersion);
213 					RESOLVE_PYTHON_SYMBOL(Py_IsInitialized);
214 					RESOLVE_PYTHON_SYMBOL(Py_Initialize);
215 					RESOLVE_PYTHON_SYMBOL(Py_Finalize);
216 					RESOLVE_PYTHON_SYMBOL(Py_NewInterpreter);
217 					RESOLVE_PYTHON_SYMBOL(Py_EndInterpreter);
218 					RESOLVE_PYTHON_SYMBOL(Py_GetPath);
219 					RESOLVE_PYTHON_SYMBOL(Py_SetPath);
220 					RESOLVE_PYTHON_SYMBOL(PySys_SetPath);
221 					RESOLVE_PYTHON_SYMBOL(Py_SetProgramName);
222 					RESOLVE_PYTHON_SYMBOL(Py_GetProgramFullPath);
223 					RESOLVE_PYTHON_SYMBOL(PyImport_AppendInittab);
224 					RESOLVE_PYTHON_SYMBOL(PyType_Ready);
225 					RESOLVE_PYTHON_SYMBOL(PyCallable_Check);
226 					RESOLVE_PYTHON_SYMBOL(PyObject_GetAttrString);
227 					RESOLVE_PYTHON_SYMBOL(PyObject_HasAttrString);
228 					RESOLVE_PYTHON_SYMBOL(PyBytes_AsString);
229 					RESOLVE_PYTHON_SYMBOL(PyBytes_Size);
230 					RESOLVE_PYTHON_SYMBOL(PyUnicode_AsASCIIString);
231 					RESOLVE_PYTHON_SYMBOL(PyUnicode_FromString);
232 					RESOLVE_PYTHON_SYMBOL(PyUnicode_AsWideCharString);
233 					RESOLVE_PYTHON_SYMBOL(PyUnicode_AsUTF8);
234 					RESOLVE_PYTHON_SYMBOL(PyByteArray_AsString);
235 					RESOLVE_PYTHON_SYMBOL(PyUnicode_FromKindAndData);
236 					RESOLVE_PYTHON_SYMBOL(PyLong_FromLong);
237 					RESOLVE_PYTHON_SYMBOL(PyLong_AsLongLong);
238 					RESOLVE_PYTHON_SYMBOL(PyModule_GetDict);
239 					RESOLVE_PYTHON_SYMBOL(PyDict_New);
240 					RESOLVE_PYTHON_SYMBOL(PyDict_Clear);
241 					RESOLVE_PYTHON_SYMBOL(PyDict_Size);
242 					RESOLVE_PYTHON_SYMBOL(PyDict_GetItem);
243 					RESOLVE_PYTHON_SYMBOL(PyDict_GetItemString);
244 					RESOLVE_PYTHON_SYMBOL(PyDict_SetItemString);
245 					RESOLVE_PYTHON_SYMBOL(PyDict_SetItem);
246 					RESOLVE_PYTHON_SYMBOL(PyDict_DelItem);
247 					RESOLVE_PYTHON_SYMBOL(PyDict_Next);
248 					RESOLVE_PYTHON_SYMBOL(PyDict_Items);
249 					RESOLVE_PYTHON_SYMBOL(PyList_New);
250 					RESOLVE_PYTHON_SYMBOL(PyList_Size);
251 					RESOLVE_PYTHON_SYMBOL(PyTuple_Size);
252 					RESOLVE_PYTHON_SYMBOL(PyList_GetItem);
253 					RESOLVE_PYTHON_SYMBOL(PyTuple_GetItem);
254 					RESOLVE_PYTHON_SYMBOL(PyList_SetItem);
255 					RESOLVE_PYTHON_SYMBOL(PyList_Append);
256 					RESOLVE_PYTHON_SYMBOL(PyModule_GetState);
257 					RESOLVE_PYTHON_SYMBOL(PyState_FindModule);
258 					RESOLVE_PYTHON_SYMBOL(PyErr_Clear);
259 					RESOLVE_PYTHON_SYMBOL(PyErr_Fetch);
260 					RESOLVE_PYTHON_SYMBOL(PyImport_ImportModule);
261 					RESOLVE_PYTHON_SYMBOL(PyObject_CallObject);
262 					RESOLVE_PYTHON_SYMBOL(PyFrame_GetLineNumber);
263 					RESOLVE_PYTHON_SYMBOL(PyEval_InitThreads);
264 					RESOLVE_PYTHON_SYMBOL(PyEval_ThreadsInitialized);
265 					RESOLVE_PYTHON_SYMBOL(PyThreadState_Get);
266 					RESOLVE_PYTHON_SYMBOL(PyEval_SaveThread);
267 					RESOLVE_PYTHON_SYMBOL(PyEval_RestoreThread);
268 					RESOLVE_PYTHON_SYMBOL(PyEval_ReleaseLock);
269 					RESOLVE_PYTHON_SYMBOL(PyThreadState_Swap);
270 					RESOLVE_PYTHON_SYMBOL(PyGILState_Check);
271 					RESOLVE_PYTHON_SYMBOL(_Py_NegativeRefcount);
272 					RESOLVE_PYTHON_SYMBOL(_PyObject_New);
273 #ifdef _DEBUG
274 					RESOLVE_PYTHON_SYMBOL(PyModule_Create2TraceRefs);
275 #else
276 					RESOLVE_PYTHON_SYMBOL(PyModule_Create2);
277 #endif
278 					RESOLVE_PYTHON_SYMBOL(PyModule_AddObject);
279 					RESOLVE_PYTHON_SYMBOL(PyArg_ParseTuple);
280 					RESOLVE_PYTHON_SYMBOL(PyArg_ParseTupleAndKeywords);
281 					RESOLVE_PYTHON_SYMBOL(PyUnicode_FromFormat);
282 					RESOLVE_PYTHON_SYMBOL(Py_BuildValue);
283 					RESOLVE_PYTHON_SYMBOL(PyMem_Free);
284 #ifdef _DEBUG
285 					RESOLVE_PYTHON_SYMBOL(_Py_Dealloc);
286 #endif
287                     RESOLVE_PYTHON_SYMBOL(PyRun_SimpleFileExFlags);
288                     RESOLVE_PYTHON_SYMBOL(PyRun_SimpleStringFlags);
289 					RESOLVE_PYTHON_SYMBOL(PyBool_FromLong);
290 					RESOLVE_PYTHON_SYMBOL(PyCapsule_Import);
291 					RESOLVE_PYTHON_SYMBOL(PyType_GenericAlloc);
292 					RESOLVE_PYTHON_SYMBOL(PyUnicode_DecodeUTF8);
293 					RESOLVE_PYTHON_SYMBOL(PyUnicode_GetLength);
294 					RESOLVE_PYTHON_SYMBOL(PyType_IsSubtype);
295 					RESOLVE_PYTHON_SYMBOL(PyByteArray_Size);
296 					RESOLVE_PYTHON_SYMBOL(PyErr_Occurred);
297 					RESOLVE_PYTHON_SYMBOL(PyLong_AsLong);
298 					RESOLVE_PYTHON_SYMBOL(PyUnicode_AsUTF8String);
299 					RESOLVE_PYTHON_SYMBOL(PyImport_AddModule);
300 					RESOLVE_PYTHON_SYMBOL(PyEval_SetProfile);
301 					RESOLVE_PYTHON_SYMBOL(PyEval_SetTrace);
302 					RESOLVE_PYTHON_SYMBOL(PyObject_Str);
303 					RESOLVE_PYTHON_SYMBOL(PyObject_IsTrue);
304 					RESOLVE_PYTHON_SYMBOL(PyFloat_AsDouble);
305 					RESOLVE_PYTHON_SYMBOL(PyObject_GetIter);
306 					RESOLVE_PYTHON_SYMBOL(PyIter_Next);
307 				}
308 			}
309 			_Py_NoneStruct.ob_refcnt = 1;
310 		};
~SharedLibraryProxySharedLibraryProxy311 		~SharedLibraryProxy() {};
312 
Py_LoadLibrarySharedLibraryProxy313 		bool Py_LoadLibrary() { return (shared_lib_ != 0); };
314 
315 #ifndef WIN32
316 		private:
317 			void FindLibrary(const std::string &sLibrary, bool bSimple = false)
318 			{
319 				std::string library;
320 				if (bSimple)
321 				{
322 					// look in directories covered by ldconfig
323 					if (!shared_lib_)
324 					{
325 						library = "lib" + sLibrary + ".so";
326 						shared_lib_ = dlopen(library.c_str(), RTLD_LAZY | RTLD_GLOBAL);
327 					}
328 					// look in directories covered by ldconfig but 'm' variant
329 					if (!shared_lib_)
330 					{
331 						library = "lib" + sLibrary + "m.so";
332 						shared_lib_ = dlopen(library.c_str(), RTLD_LAZY | RTLD_GLOBAL);
333 					}
334 					// look in /usr/lib directories
335 					if (!shared_lib_)
336 					{
337 						library = "/usr/lib/" + sLibrary + "/";
338 						FindLibrary(library, false);
339 					}
340 					// look in /usr/lib directories but 'm' variant
341 					if (!shared_lib_)
342 					{
343 						library = "/usr/lib/" + sLibrary + "m/";
344 						FindLibrary(library, false);
345 					}
346 					// look in /usr/local/lib directory (handles build from source)
347 					if (!shared_lib_)
348 					{
349 						library = "/usr/local/lib/lib" + sLibrary + ".so";
350 						shared_lib_ = dlopen(library.c_str(), RTLD_LAZY | RTLD_GLOBAL);
351 
352 					}
353 					// look in /usr/local/lib directory (handles build from source) but 'm' variant
354 					if (!shared_lib_)
355 					{
356 						library = "/usr/local/lib/lib" + sLibrary + "m.so";
357 						shared_lib_ = dlopen(library.c_str(), RTLD_LAZY | RTLD_GLOBAL);
358 					}
359 					// MacOS
360 					// look for .dylib in /usr/local/lib
361 					if (!shared_lib_)
362 					{
363 						library = "/usr/local/lib/lib" + sLibrary + ".dylib";
364 						shared_lib_ = dlopen(library.c_str(), RTLD_LAZY | RTLD_GLOBAL);
365 					}
366 					// look for .dylib in /Library/Frameworks/Python.framework/Versions/*/lib
367 					if (!shared_lib_)
368 					{
369 						library = "/Library/Frameworks/Python.framework/Versions/"+sLibrary.substr(sLibrary.size() - 3)+"/lib/lib" + sLibrary + ".dylib";
370 						shared_lib_ = dlopen(library.c_str(), RTLD_LAZY | RTLD_GLOBAL);
371 					}
372 					// Finally look for .dylib installed by Homebrew
373 					if (!shared_lib_)
374 					{
375 						library = "/usr/local/Frameworks/Python.framework/Versions/"+sLibrary.substr(sLibrary.size() - 3)+"/lib/lib" + sLibrary + ".dylib";
376 						shared_lib_ = dlopen(library.c_str(), RTLD_LAZY | RTLD_GLOBAL);
377 					}
378 				}
379 				else
380 				{
381 					std::vector<std::string> entries;
382 					std::vector<std::string>::const_iterator itt;
383 					DirectoryListing(entries, sLibrary, true, false);
384 					for (itt = entries.begin(); !shared_lib_ && itt != entries.end(); ++itt)
385 					{
386 						library = sLibrary + *itt + "/";
387 						FindLibrary(library, false);
388 					}
389 
390 					std::string filename;
391 					entries.clear();
392 					DirectoryListing(entries, sLibrary, false, true);
393 					for (itt = entries.begin(); !shared_lib_ && itt != entries.end(); ++itt)
394 					{
395 						filename = *itt;
396 						if (filename.length() > 12 &&
397 							filename.compare(0, 11, "libpython3.") == 0 &&
398 							filename.compare(filename.length() - 3, 3, ".so") == 0 &&
399 							filename.compare(filename.length() - 6, 6, ".dylib") == 0)
400 						{
401 							library = sLibrary + filename;
402 							shared_lib_ = dlopen(library.c_str(), RTLD_LAZY | RTLD_GLOBAL);
403 						}
404 
405 					}
406 				}
407 			}
408 #endif
409 	};
410 
411 extern	SharedLibraryProxy* pythonLib;
412 
413 #define	Py_LoadLibrary			pythonLib->Py_LoadLibrary
414 #define	Py_GetVersion			pythonLib->Py_GetVersion
415 #define	Py_IsInitialized		pythonLib->Py_IsInitialized
416 #define	Py_Initialize			pythonLib->Py_Initialize
417 #define	Py_Finalize				pythonLib->Py_Finalize
418 #define	Py_NewInterpreter		pythonLib->Py_NewInterpreter
419 #define	Py_EndInterpreter		pythonLib->Py_EndInterpreter
420 #define	Py_SetPath				pythonLib->Py_SetPath
421 #define	PySys_SetPath			pythonLib->PySys_SetPath
422 #define	Py_GetPath				pythonLib->Py_GetPath
423 #define	Py_SetProgramName		pythonLib->Py_SetProgramName
424 #define	Py_GetProgramFullPath	pythonLib->Py_GetProgramFullPath
425 #define	PyImport_AppendInittab	pythonLib->PyImport_AppendInittab
426 #define	PyType_Ready			pythonLib->PyType_Ready
427 #define	PyCallable_Check		pythonLib->PyCallable_Check
428 #define	PyObject_GetAttrString	pythonLib->PyObject_GetAttrString
429 #define	PyObject_HasAttrString	pythonLib->PyObject_HasAttrString
430 #define	PyBytes_AsString		pythonLib->PyBytes_AsString
431 #define	PyBytes_Size			pythonLib->PyBytes_Size
432 #define PyUnicode_AsASCIIString pythonLib->PyUnicode_AsASCIIString
433 #define PyUnicode_FromString	pythonLib->PyUnicode_FromString
434 #define PyUnicode_FromFormat	pythonLib->PyUnicode_FromFormat
435 #define PyUnicode_AsWideCharString	pythonLib->PyUnicode_AsWideCharString
436 #define PyUnicode_AsUTF8		pythonLib->PyUnicode_AsUTF8
437 #define PyByteArray_AsString	pythonLib->PyByteArray_AsString
438 #define PyUnicode_FromKindAndData  pythonLib->PyUnicode_FromKindAndData
439 #define PyLong_FromLong			pythonLib->PyLong_FromLong
440 #define PyLong_AsLongLong		pythonLib->PyLong_AsLongLong
441 #define PyModule_GetDict		pythonLib->PyModule_GetDict
442 #define PyDict_New				pythonLib->PyDict_New
443 #define PyDict_Clear			pythonLib->PyDict_Clear
444 #define PyDict_Size				pythonLib->PyDict_Size
445 #define PyDict_GetItem			pythonLib->PyDict_GetItem
446 #define PyDict_GetItemString	pythonLib->PyDict_GetItemString
447 #define PyDict_SetItemString	pythonLib->PyDict_SetItemString
448 #define PyDict_SetItem			pythonLib->PyDict_SetItem
449 #define PyDict_DelItem			pythonLib->PyDict_DelItem
450 #define PyDict_Next				pythonLib->PyDict_Next
451 #define PyDict_Items			pythonLib->PyDict_Items
452 #define PyList_New				pythonLib->PyList_New
453 #define PyList_Size				pythonLib->PyList_Size
454 #define PyTuple_Size			pythonLib->PyTuple_Size
455 #define PyList_GetItem			pythonLib->PyList_GetItem
456 #define PyTuple_GetItem			pythonLib->PyTuple_GetItem
457 #define PyList_SetItem			pythonLib->PyList_SetItem
458 #define PyList_Append			pythonLib->PyList_Append
459 #define PyModule_GetState		pythonLib->PyModule_GetState
460 #define PyState_FindModule		pythonLib->PyState_FindModule
461 #define PyErr_Clear				pythonLib->PyErr_Clear
462 #define PyErr_Fetch				pythonLib->PyErr_Fetch
463 #define PyImport_ImportModule	pythonLib->PyImport_ImportModule
464 #define PyObject_CallObject		pythonLib->PyObject_CallObject
465 #define PyFrame_GetLineNumber	pythonLib->PyFrame_GetLineNumber
466 #define	PyEval_InitThreads		pythonLib->PyEval_InitThreads
467 #define	PyEval_ThreadsInitialized	pythonLib->PyEval_ThreadsInitialized
468 #define	PyThreadState_Get		pythonLib->PyThreadState_Get
469 #define PyEval_SaveThread		pythonLib->PyEval_SaveThread
470 #define PyEval_RestoreThread	pythonLib->PyEval_RestoreThread
471 #define PyEval_ReleaseLock		pythonLib->PyEval_ReleaseLock
472 #define PyThreadState_Swap		pythonLib->PyThreadState_Swap
473 #define PyGILState_Check		pythonLib->PyGILState_Check
474 #define _Py_NegativeRefcount	pythonLib->_Py_NegativeRefcount
475 #define _PyObject_New			pythonLib->_PyObject_New
476 #define PyArg_ParseTuple		pythonLib->PyArg_ParseTuple
477 #define Py_BuildValue			pythonLib->Py_BuildValue
478 #define PyMem_Free				pythonLib->PyMem_Free
479 #ifdef _DEBUG
480 #	define PyModule_Create2TraceRefs pythonLib->PyModule_Create2TraceRefs
481 #else
482 #	define PyModule_Create2		pythonLib->PyModule_Create2
483 #endif
484 #define PyModule_AddObject		pythonLib->PyModule_AddObject
485 #define PyArg_ParseTupleAndKeywords pythonLib->PyArg_ParseTupleAndKeywords
486 
487 #ifdef _DEBUG
488 #	define _Py_Dealloc			pythonLib->_Py_Dealloc
489 #endif
490 
491 #define _Py_RefTotal			pythonLib->_Py_RefTotal
492 #define _Py_NoneStruct			pythonLib->_Py_NoneStruct
493 #define PyRun_SimpleStringFlags pythonLib->PyRun_SimpleStringFlags
494 #define PyRun_SimpleFileExFlags pythonLib->PyRun_SimpleFileExFlags
495 #define PyBool_FromLong			pythonLib->PyBool_FromLong
496 #define PyCapsule_Import		pythonLib->PyCapsule_Import
497 #define PyType_GenericAlloc		pythonLib->PyType_GenericAlloc
498 #define PyUnicode_DecodeUTF8	pythonLib->PyUnicode_DecodeUTF8
499 #define PyUnicode_GetLength		pythonLib->PyUnicode_GetLength
500 #define PyType_IsSubtype		pythonLib->PyType_IsSubtype
501 #define PyByteArray_Size		pythonLib->PyByteArray_Size
502 #define PyErr_Occurred			pythonLib->PyErr_Occurred
503 #define PyLong_AsLong			pythonLib->PyLong_AsLong
504 #define PyUnicode_AsUTF8String	pythonLib->PyUnicode_AsUTF8String
505 #define PyImport_AddModule		pythonLib->PyImport_AddModule
506 #define PyEval_SetProfile		pythonLib->PyEval_SetProfile
507 #define PyEval_SetTrace			pythonLib->PyEval_SetTrace
508 #define PyObject_Str			pythonLib->PyObject_Str
509 #define	PyObject_IsTrue			pythonLib->PyObject_IsTrue
510 #define PyFloat_AsDouble		pythonLib->PyFloat_AsDouble
511 #define	PyObject_GetIter		pythonLib->PyObject_GetIter
512 #define	PyIter_Next				pythonLib->PyIter_Next
513 }
514