1
0

obs-scripting-python-import.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /******************************************************************************
  2. Copyright (C) 2017 by Hugh Bailey <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ******************************************************************************/
  14. #include <util/dstr.h>
  15. #include <util/platform.h>
  16. #define NO_REDEFS
  17. #include "obs-scripting-python-import.h"
  18. #include "obs-scripting-config.h"
  19. #ifdef _MSC_VER
  20. #pragma warning(disable : 4152)
  21. #endif
  22. #ifdef _WIN32
  23. #define SO_EXT ".dll"
  24. #elif __APPLE__
  25. #define SO_EXT ".dylib"
  26. #endif
  27. #ifdef __APPLE__
  28. #define PYTHON_LIB_SUBDIR "lib/"
  29. #else
  30. #define PYTHON_LIB_SUBDIR ""
  31. #endif
  32. bool import_python(const char *python_path)
  33. {
  34. struct dstr lib_path;
  35. bool success = false;
  36. void *lib;
  37. if (!python_path)
  38. python_path = "";
  39. dstr_init_copy(&lib_path, python_path);
  40. dstr_replace(&lib_path, "\\", "/");
  41. if (!dstr_is_empty(&lib_path)) {
  42. dstr_cat(&lib_path, "/" PYTHON_LIB_SUBDIR);
  43. }
  44. dstr_cat(&lib_path, PYTHON_LIB SO_EXT);
  45. lib = os_dlopen(lib_path.array);
  46. if (!lib) {
  47. blog(LOG_WARNING, "[Python] Could not load library: %s",
  48. lib_path.array);
  49. goto fail;
  50. }
  51. #define IMPORT_FUNC(x) \
  52. do { \
  53. Import_##x = os_dlsym(lib, #x); \
  54. if (!Import_##x) { \
  55. blog(LOG_WARNING, "[Python] Failed to import: %s", \
  56. #x); \
  57. goto fail; \
  58. } \
  59. } while (false)
  60. IMPORT_FUNC(PyType_Ready);
  61. IMPORT_FUNC(PyObject_GenericGetAttr);
  62. IMPORT_FUNC(PyObject_IsTrue);
  63. IMPORT_FUNC(Py_DecRef);
  64. IMPORT_FUNC(PyObject_Malloc);
  65. IMPORT_FUNC(PyObject_Free);
  66. IMPORT_FUNC(PyObject_Init);
  67. IMPORT_FUNC(PyUnicode_FromFormat);
  68. IMPORT_FUNC(PyUnicode_Concat);
  69. IMPORT_FUNC(PyLong_FromVoidPtr);
  70. IMPORT_FUNC(PyBool_FromLong);
  71. IMPORT_FUNC(PyGILState_Ensure);
  72. IMPORT_FUNC(PyGILState_GetThisThreadState);
  73. IMPORT_FUNC(PyErr_SetString);
  74. IMPORT_FUNC(PyErr_Occurred);
  75. IMPORT_FUNC(PyErr_Fetch);
  76. IMPORT_FUNC(PyErr_Restore);
  77. IMPORT_FUNC(PyErr_WriteUnraisable);
  78. IMPORT_FUNC(PyArg_UnpackTuple);
  79. IMPORT_FUNC(Py_BuildValue);
  80. IMPORT_FUNC(PyRun_SimpleStringFlags);
  81. IMPORT_FUNC(PyErr_Print);
  82. IMPORT_FUNC(Py_SetPythonHome);
  83. IMPORT_FUNC(Py_Initialize);
  84. IMPORT_FUNC(Py_Finalize);
  85. IMPORT_FUNC(Py_IsInitialized);
  86. IMPORT_FUNC(PyEval_InitThreads);
  87. IMPORT_FUNC(PyEval_ThreadsInitialized);
  88. IMPORT_FUNC(PyEval_ReleaseThread);
  89. IMPORT_FUNC(PySys_SetArgv);
  90. IMPORT_FUNC(PyImport_ImportModule);
  91. IMPORT_FUNC(PyObject_CallFunctionObjArgs);
  92. IMPORT_FUNC(_Py_NotImplementedStruct);
  93. IMPORT_FUNC(PyExc_TypeError);
  94. IMPORT_FUNC(PyExc_RuntimeError);
  95. IMPORT_FUNC(PyObject_GetAttr);
  96. IMPORT_FUNC(PyUnicode_FromString);
  97. IMPORT_FUNC(PyDict_GetItemString);
  98. IMPORT_FUNC(PyDict_SetItemString);
  99. IMPORT_FUNC(PyCFunction_NewEx);
  100. IMPORT_FUNC(PyModule_GetDict);
  101. IMPORT_FUNC(PyModule_GetNameObject);
  102. IMPORT_FUNC(PyModule_AddObject);
  103. IMPORT_FUNC(PyModule_AddStringConstant);
  104. IMPORT_FUNC(PyImport_Import);
  105. IMPORT_FUNC(PyObject_CallObject);
  106. IMPORT_FUNC(_Py_FalseStruct);
  107. IMPORT_FUNC(_Py_TrueStruct);
  108. IMPORT_FUNC(PyGILState_Release);
  109. IMPORT_FUNC(PyList_Append);
  110. IMPORT_FUNC(PySys_GetObject);
  111. IMPORT_FUNC(PyImport_ReloadModule);
  112. IMPORT_FUNC(PyObject_GetAttrString);
  113. IMPORT_FUNC(PyCapsule_New);
  114. IMPORT_FUNC(PyCapsule_GetPointer);
  115. IMPORT_FUNC(PyArg_ParseTuple);
  116. IMPORT_FUNC(PyFunction_Type);
  117. IMPORT_FUNC(PyObject_SetAttr);
  118. IMPORT_FUNC(_PyObject_New);
  119. IMPORT_FUNC(PyCapsule_Import);
  120. IMPORT_FUNC(PyErr_Clear);
  121. IMPORT_FUNC(PyObject_Call);
  122. IMPORT_FUNC(PyList_New);
  123. IMPORT_FUNC(PyList_Size);
  124. IMPORT_FUNC(PyList_GetItem);
  125. IMPORT_FUNC(PyUnicode_AsUTF8String);
  126. IMPORT_FUNC(PyLong_FromUnsignedLongLong);
  127. IMPORT_FUNC(PyArg_VaParse);
  128. IMPORT_FUNC(_Py_NoneStruct);
  129. #undef IMPORT_FUNC
  130. success = true;
  131. fail:
  132. if (!success && lib)
  133. os_dlclose(lib);
  134. dstr_free(&lib_path);
  135. return success;
  136. }