Question: I am trying to embed Python inside my C++ DLL. The idea is that the DLL, once distributed, should be sufficient and not rely on other installations and downloads. Interestingly, the below "sort of" works, only in my solution directory, since that is where my vcpkg_installed is. How can I make my DLL not be required to be near vcpkg_installed? Code py_wrap.cpp (the DLL): void assertPyInit() { if (!Py_IsInitialized()) { PyConfig config; PyConfig_InitPythonConfig(&config); // Get the executable path instead of current working directory wchar_t exePath[MAX_PATH]; GetModuleFileNameW(NULL, exePath, MAX_PATH); // Remove the executable name to get the directory std::wstring exeDir = exePath; size_t lastSlash = exeDir.find_last_of(L"\\"); if (lastSlash != std::wstring::npos) { exeDir = exeDir.substr(0, lastSlash); } // Now build Python path relative to executable location std::wstring pythonHome = exeDir + L"\\..\\..\\vcpkg_installed\\x64-windows-static-md\\x64-windows-static-md\\tools\\python3"; // Resolve the full path to eliminate .. references wchar_t resolvedPath[MAX_PATH]; GetFullPathNameW(pythonHome.c_str(), MAX_PATH, resolvedPath, NULL); pythonHome = resolvedPath; std::wstring pythonLib = pythonHome + L"\\Lib"; std::wstring pythonSitePackages = pythonLib + L"\\site-packages"; std::wstring pythonDLLs = pythonHome + L"\\DLLs"; // Set the Python home directory PyConfig_SetString(&config, &config.home, pythonHome.c_str()); // Set the module search paths std::wstring pythonPathEnv = pythonLib + L";" + pythonSitePackages + L";" + pythonDLLs; PyConfig_SetString(&config, &config.pythonpath_env, pythonPathEnv.c_str()); PyStatus status = Py_InitializeFromConfig(&config); PyConfig_Clear(&config); if (PyStatus_Exception(status)) { PyErr_Print(); return; } PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.append(\".\")"); } } void MY_DLL pyPrint(const char* message) { assertPyInit(); PyObject* pyStr = PyUnicode_FromString(message); if (pyStr) { PyObject* builtins = PyEval_GetBuiltins(); PyObject* printFunc = PyDict_GetItemString(builtins, "print"); if (printFunc && PyCallable_Check(printFunc)) { PyObject* args = PyTuple_Pack(1, pyStr); PyObject_CallObject(printFunc, args); Py_DECREF(args); } Py_DECREF(pyStr); } }  DLLTester.cpp (client app): #include <iostream> #include "py_wrap.h" int main() { std::cout << "Hello\n"; pyPrint("Hello from python:D !"); }  File structure and IO PS D: \RedactedLabs\Dev > ls AsyncDLLMQL\x64\Release\ Directory: D: \RedactedLabs\Dev\AsyncDLLMQL\x64\Release Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 6/11/2025 10:48 PM 476672 AsyncDLLMQL.dll -a---- 6/11/2025 10:48 PM 4297 AsyncDLLMQL.exp -a---- 6/11/2025 10:26 PM 7752 AsyncDLLMQL.lib -a---- 6/11/2025 10:48 PM 7376896 AsyncDLLMQL.pdb -a---- 6/11/2025 10:48 PM 12288 DLLTester.exe -a---- 6/11/2025 10:48 PM 790528 DLLTester.pdb -a---- 6/6/2025 4: 39 PM 56320 python3.dll -a---- 6/6/2025 4: 39 PM 7273984 python312.dll PS D: \RedactedLabs\Dev > ls AsyncDLLMQL\x64\Release\ Directory: D: \RedactedLabs\Dev\AsyncDLLMQL\x64\Release Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 6/11/2025 10:48 PM 476672 AsyncDLLMQL.dll -a---- 6/11/2025 10:48 PM 4297 AsyncDLLMQL.exp -a---- 6/11/2025 10:26 PM 7752 AsyncDLLMQL.lib -a---- 6/11/2025 10:48 PM 7376896 AsyncDLLMQL.pdb -a---- 6/11/2025 10:48 PM 12288 DLLTester.exe -a---- 6/11/2025 10:48 PM 790528 DLLTester.pdb -a---- 6/6/2025 4: 39 PM 56320 python3.dll -a---- 6/6/2025 4: 39 PM 7273984 python312.dll PS D: \RedactedLabs\Dev > ls .\scraps\ Directory: D: \RedactedLabs\Dev\scraps Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 6/11/2025 10:48 PM 476672 AsyncDLLMQL.dll -a---- 6/11/2025 10:48 PM 4297 AsyncDLLMQL.exp -a---- 6/11/2025 10:26 PM 7752 AsyncDLLMQL.lib -a---- 6/11/2025 10:48 PM 7376896 AsyncDLLMQL.pdb -a---- 6/11/2025 10:48 PM 12288 DLLTester.exe -a---- 6/11/2025 10:48 PM 790528 DLLTester.pdb -a---- 6/6/2025 4: 39 PM 56320 python3.dll -a---- 6/6/2025 4: 39 PM 7273984 python312.dll PS D: \RedactedLabs\Dev > .\AsyncDLLMQL\x64\Release\DLLTester.exe Hello Hello from python: D ! PS D: \RedactedLabs\Dev > .\scraps\DLLTester.exe Hello Python path configuration: PYTHONHOME= 'D:\RedactedLabs\vcpkg_installed\x64-windows-static-md\x64-windows-static-md\tools\python3' PYTHONPATH = 'D:\RedactedLabs\vcpkg_installed\x64-windows-static-md\x64-windows-static-md\tools\python3\Lib;D:\RedactedLabs\vcpkg_installed\x64-windows-static-md\x64-windows-static-md\tools\python3\Lib\site-packages;D:\RedactedLabs\vcpkg_installed\x64-windows-static-md\x64-windows-static-md\tools\python3\DLLs' program name = 'python' isolated = 0 environment = 1 user site = 1 safe_path = 0 import site = 1 is in build tree = 0 stdlib dir = 'D:\RedactedLabs\vcpkg_installed\x64-windows-static-md\x64-windows-static-md\tools\python3\Lib' sys._base_executable = 'D:\\RedactedLabs\\Dev\\scraps\\DLLTester.exe' sys.base_prefix = 'D:\\RedactedLabs\\vcpkg_installed\\x64-windows-static-md\\x64-windows-static-md\\tools\\python3' sys.base_exec_prefix = 'D:\\RedactedLabs\\vcpkg_installed\\x64-windows-static-md\\x64-windows-static-md\\tools\\python3' sys.platlibdir = 'DLLs' sys.executable = 'D:\\RedactedLabs\\Dev\\scraps\\DLLTester.exe' sys.prefix = 'D:\\RedactedLabs\\vcpkg_installed\\x64-windows-static-md\\x64-windows-static-md\\tools\\python3' sys.exec_prefix = 'D:\\RedactedLabs\\vcpkg_installed\\x64-windows-static-md\\x64-windows-static-md\\tools\\python3' sys.path = [ 'D:\\RedactedLabs\\vcpkg_installed\\x64-windows-static-md\\x64-windows-static-md\\tools\\python3\\Lib', 'D:\\RedactedLabs\\vcpkg_installed\\x64-windows-static-md\\x64-windows-static-md\\tools\\python3\\Lib\\site-packages', 'D:\\RedactedLabs\\vcpkg_installed\\x64-windows-static-md\\x64-windows-static-md\\tools\\python3\\DLLs', 'D:\\RedactedLabs\\Dev\\scraps\\python312.zip', 'D:\\RedactedLabs\\vcpkg_installed\\x64-windows-static-md\\x64-windows-static-md\\tools\\python3\\DLLs', 'D:\\RedactedLabs\\vcpkg_installed\\x64-windows-static-md\\x64-windows-static-md\\tools\\python3\\Lib', 'D:\\RedactedLabs\\Dev\\scraps', ] ModuleNotFoundError: No module named 'encodings'  Finally, my linker settings and other useful info:  Platform: Windows IDE: Visual Studio Use Vcpkg Manifest: Yes Target triplet: "x64-windows-static-md" Additional include directories: $(SolutionDir)vcpkg_installed\x64-windows-static-md\x64-windows-static-md\include\python3.12 Additional Library Directories: $(VcpkgInstalledDir)\x64-windows-static-md\lib 

Answer: CPython needs its standard library to exist at the PYTHONHOME directory, (which you can override in the config). If you need a standalone python interpreter to just parse python syntax (for game scripting) then you can use other implementations of python like RustPython or IronPython or JYThon or pocketpy, but you won't be able to use any C/C++ libraries like numpy. If security is not a concern then you can do as popular apps like blender do and package the interpreter with your application and set PYTHONHOME before initializing the interpreter with Py_InitializeFromConfig as in the following structure. . └── app_root/ ├── app.exe ├── python311.dll └── python/ ├── DLLs/ │ ├── _ctypes.pyd │ └── ... ├── Lib/ │ ├── site_packages/ │ │ └── numpy, etc... │ ├── os.py │ └── ... └── bin (optional)/ ├── python311.dll (see note below) └── python.exe (see note below)  If you place python311.dll in a subdirectory then you must do extra steps to set the PATH to its location or use LoadLibrary instead and not link it directly. packing python.exe allows your user to install extra libraries using pip by doing python.exe -m pip install ... keep in mind that users will be able to modify everything, so if security is a concern then my recommendation is not to use Python ... but you can create a custom importer and static link everything and get it to work. note that a game did this before as well as create custom byte-code for the interpreter and was still completely reverse engineered, so this is not really fool-proof.