[3.9] bpo-29778: Ensure python3.dll is loaded from correct locations when Python is embedded (GH-21297) by miss-islington · Pull Request #21351 · python/cpython
wchar_t *dll_path;
const wchar_t *pythonpath_env; } PyCalculatePath;
while (i > 0 && src[i] != '.' && !is_sep(src[i])) --i; while (i > 0 && src[i] != '.' && !is_sep(src[i])) --i;
if (i == 0) { dest[0] = '\0'; return -1; } if (i == 0) { dest[0] = '\0'; return -1; }
if (is_sep(src[i])) { i = src_len; }
if (is_sep(src[i])) { i = src_len; if (wcsncpy_s(dest, MAXPATHLEN+1, src, i)) { dest[0] = '\0'; return -1; } } else { wchar_t *s = wcsrchr(dest, L'.'); if (s) { s[0] = '\0'; } }
if (wcsncpy_s(dest, MAXPATHLEN+1, src, i) || wcscat_s(dest, MAXPATHLEN+1, ext)) { if (wcscat_s(dest, MAXPATHLEN+1, ext)) { dest[0] = '\0'; return -1; }
static int get_dllpath(wchar_t *dllpath) { #ifdef Py_ENABLE_SHARED extern HANDLE PyWin_DLLhModule; if (PyWin_DLLhModule && GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN)) { return 0; } #endif return -1; }
#ifdef Py_ENABLE_SHARED
/* a string loaded from the DLL at startup.*/
wchar_t* _Py_GetDLLPath(void) { wchar_t dll_path[MAXPATHLEN+1]; memset(dll_path, 0, sizeof(dll_path));
#ifdef Py_ENABLE_SHARED extern HANDLE PyWin_DLLhModule; if (PyWin_DLLhModule) { if (!GetModuleFileNameW(PyWin_DLLhModule, dll_path, MAXPATHLEN)) { dll_path[0] = 0; } } #else dll_path[0] = 0; #endif
return _PyMem_RawWcsdup(dll_path); }
static PyStatus get_program_full_path(_PyPathConfig *pathconfig) {
change_ext(zip_path, calculate->dll_path[0] ? calculate->dll_path : pathconfig->program_full_path, L".zip"); if (get_dllpath(zip_path) || change_ext(zip_path, zip_path, L".zip")) { if (change_ext(zip_path, pathconfig->program_full_path, L".zip")) { zip_path[0] = L'\0'; } }
calculate_home_prefix(calculate, argv0_path, zip_path, prefix);
calculate->dll_path = _Py_GetDLLPath(); if (calculate->dll_path == NULL) { return _PyStatus_NO_MEMORY(); }
calculate->pythonpath_env = config->pythonpath_env;
return _PyStatus_OK();
- PyConfig.pythonpath_env: PYTHONPATH environment variable - _PyPathConfig.home: Py_SetPythonHome() or PYTHONHOME environment variable - DLL path: _Py_GetDLLPath() - PATH environment variable - __PYVENV_LAUNCHER__ environment variable - GetModuleFileNameW(NULL): fully qualified path of the executable file of
/* If there is a python3.dll next to the python3y.dll, assume this is a build tree; use that DLL */ if (_Py_dll_path != NULL) { wcscpy(py3path, _Py_dll_path); } else { wcscpy(py3path, L""); } s = wcsrchr(py3path, L'\\'); if (!s) { s = py3path; use that DLL */ if (!get_dllpath(py3path)) { reduce(py3path); join(py3path, PY3_DLLNAME); hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); if (hPython3 != NULL) { return 1; } } wcscpy(s, L"\\python3.dll"); hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
/* If we can locate python3.dll in our application dir, use that DLL */ hPython3 = LoadLibraryExW(PY3_DLLNAME, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR); if (hPython3 != NULL) { return 1; }
/* Check sys.prefix\DLLs\python3.dll */ /* For back-compat, also search {sys.prefix}\DLLs, though that has not been a normal install layout for a while */ wcscpy(py3path, Py_GetPrefix()); wcscat(py3path, L"\\DLLs\\python3.dll"); hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (py3path[0]) { join(py3path, L"DLLs\\" PY3_DLLNAME); hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); } return hPython3 != NULL; }