int main() { LPWSTR *szArglist; int nArgs; wchar_t wszPath[10240]; wchar_t wszCmd[10240]; wchar_t *p; char* szCmd; GetModuleFileNameW(NULL, wszPath, sizeof(wszPath)); p = wcsrchr(wszPath, L'\\'); if (p == NULL) { printf("Get module file name error!\n"); return -1; } *p = 0; szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); swprintf(wszCmd, L"PATH=%s\\DLLs;%%PATH%%", wszPath); _wputenv(wszCmd); Py_NoSiteFlag = 1; Py_SetPythonHome(wszPath); swprintf(wszCmd, L"%s\\Lib", wszPath); Py_SetPath(wszCmd); Py_Initialize(); PySys_SetArgv(nArgs-1, szArglist+1); swprintf(wszCmd, L"import sys\n" L"cur = r'%s'\n" L"join = lambda *args: '\\\\'.join(args)\n" L"sys.path = [join(cur, f) for f in ['', 'Lib', 'Lib/libstdpy.zip', 'site-packages', 'DLLs']]\n" L"import os; join = os.path.join\n" L"sys.path += [join(cur, 'Lib', f) for f in os.listdir(join(cur, 'Lib')) if f.endswith('.zip') and f != 'libstdpy.zip']\n" L"sys.path.insert(1, join(cur, 'src.zip'))\n" L"m = r'%s'\n" L"sys.path.insert(0, os.path.split(m)[0])\n" L"import imp; imp.load_source('__main__', m)\n", wszPath, *(szArglist+1)); /* wprintf(wszCmd); */ szCmd = to_utf8(wszCmd); PyRun_SimpleString(szCmd); free(szCmd); LocalFree(szArglist); return 0; }
VOID AppendPackage() { PLDR_MODULE Self; UNICODE_STRING SelfPath; static WCHAR PythonZip[] = L"python.zip"; ml::MlInitialize(); //Py_IgnoreEnvironmentFlag = TRUE; //Py_NoSiteFlag = TRUE; Py_DontWriteBytecodeFlag = TRUE; //Py_NoUserSiteDirectory = TRUE; Self = FindLdrModuleByHandle(nullptr); SelfPath = Self->FullDllName; SelfPath.Length -= Self->BaseDllName.Length; Py_SetPath(ml::String::Format( L"%wZ;%wZ%s;%wZ%s\\site-packages;%wZlib;%wZDLLs;%wZUserSite", &SelfPath, // exe path &SelfPath, PythonZip, // ./python.zip &SelfPath, PythonZip, // ./python.zip/site-packages &SelfPath, // ./lib &SelfPath, // ./DLLs &SelfPath // ./UserSite )); ml::String PathEnv, UserSite; PWSTR EnvBuffer; ULONG Length; UNICODE_STRING Path; RtlInitEmptyString(&Path); RtlExpandEnvironmentStrings_U(nullptr, &USTR(L"%Path%"), &Path, &Length); EnvBuffer = (PWSTR)AllocStack(Length); RtlInitEmptyString(&Path, EnvBuffer, Length); RtlExpandEnvironmentStrings_U(nullptr, &USTR(L"%Path%"), &Path, nullptr); UserSite = SelfPath; UserSite += L"UserSite"; PathEnv = SelfPath; PathEnv += L"DLLs;"; EnumDirectoryFiles( nullptr, L"*.*", 0, UserSite, nullptr, [] (PVOID Buffer, PWIN32_FIND_DATAW FindData, ULONG_PTR Context) -> LONG { ml::String *PathEnv = (ml::String *)Context; if (FLAG_OFF(FindData->dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY)) return 0; (*PathEnv) += FindData->cFileName; (*PathEnv) += ';'; return 0; }, (ULONG_PTR)&PathEnv, EDF_PROCDIR | EDF_BEFORE ); PathEnv += Path; PathEnv += ';'; RtlSetEnvironmentVariable(nullptr, &USTR(L"Path"), PathEnv); }
/* int main(int argc, char **argv) { */ int main(int argc, char *argv[]) { char *env_argument = NULL; char *env_entrypoint = NULL; char *env_logname = NULL; char entrypoint[ENTRYPOINT_MAXLEN]; int ret = 0; FILE *fd; setenv("P4A_BOOTSTRAP", "SDL2", 1); // env var to identify p4a to applications LOGP("Initializing Python for Android"); env_argument = getenv("ANDROID_ARGUMENT"); setenv("ANDROID_APP_PATH", env_argument, 1); env_entrypoint = getenv("ANDROID_ENTRYPOINT"); env_logname = getenv("PYTHON_NAME"); if (!getenv("ANDROID_UNPACK")) { /* ANDROID_UNPACK currently isn't set in services */ setenv("ANDROID_UNPACK", env_argument, 1); } if (env_logname == NULL) { env_logname = "python"; setenv("PYTHON_NAME", "python", 1); } LOGP("Changing directory to the one provided by ANDROID_ARGUMENT"); LOGP(env_argument); chdir(env_argument); Py_SetProgramName(L"android_python"); #if PY_MAJOR_VERSION >= 3 /* our logging module for android */ PyImport_AppendInittab("androidembed", initandroidembed); #endif LOGP("Preparing to initialize python"); // Set up the python path char paths[256]; char crystax_python_dir[256]; snprintf(crystax_python_dir, 256, "%s/crystax_python", getenv("ANDROID_UNPACK")); char python_bundle_dir[256]; snprintf(python_bundle_dir, 256, "%s/_python_bundle", getenv("ANDROID_UNPACK")); if (dir_exists(crystax_python_dir) || dir_exists(python_bundle_dir)) { if (dir_exists(crystax_python_dir)) { LOGP("crystax_python exists"); snprintf(paths, 256, "%s/stdlib.zip:%s/modules", crystax_python_dir, crystax_python_dir); } if (dir_exists(python_bundle_dir)) { LOGP("_python_bundle dir exists"); snprintf(paths, 256, "%s/stdlib.zip:%s/modules", python_bundle_dir, python_bundle_dir); } LOGP("calculated paths to be..."); LOGP(paths); #if PY_MAJOR_VERSION >= 3 wchar_t *wchar_paths = Py_DecodeLocale(paths, NULL); Py_SetPath(wchar_paths); #else char *wchar_paths = paths; LOGP("Can't Py_SetPath in python2, so crystax python2 doesn't work yet"); exit(1); #endif LOGP("set wchar paths..."); } else { // We do not expect to see crystax_python any more, so no point // reminding the user about it. If it does exist, we'll have // logged it earlier. LOGP("_python_bundle does not exist"); } Py_Initialize(); #if PY_MAJOR_VERSION < 3 PySys_SetArgv(argc, argv); #endif LOGP("Initialized python"); /* ensure threads will work. */ LOGP("AND: Init threads"); PyEval_InitThreads(); #if PY_MAJOR_VERSION < 3 initandroidembed(); #endif PyRun_SimpleString("import androidembed\nandroidembed.log('testing python " "print redirection')"); /* inject our bootstrap code to redirect python stdin/stdout * replace sys.path with our path */ PyRun_SimpleString("import sys, posix\n"); if (dir_exists("lib")) { /* If we built our own python, set up the paths correctly */ LOGP("Setting up python from ANDROID_PRIVATE"); PyRun_SimpleString("private = posix.environ['ANDROID_APP_PATH']\n" "argument = posix.environ['ANDROID_ARGUMENT']\n" "sys.path[:] = [ \n" " private + '/lib/python27.zip', \n" " private + '/lib/python2.7/', \n" " private + '/lib/python2.7/lib-dynload/', \n" " private + '/lib/python2.7/site-packages/', \n" " argument ]\n"); } char add_site_packages_dir[256]; if (dir_exists(crystax_python_dir)) { snprintf(add_site_packages_dir, 256, "sys.path.append('%s/site-packages')", crystax_python_dir); PyRun_SimpleString("import sys\n" "sys.argv = ['notaninterpreterreally']\n" "from os.path import realpath, join, dirname"); PyRun_SimpleString(add_site_packages_dir); /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */ PyRun_SimpleString("sys.path = ['.'] + sys.path"); } if (dir_exists(python_bundle_dir)) { snprintf(add_site_packages_dir, 256, "sys.path.append('%s/site-packages')", python_bundle_dir); PyRun_SimpleString("import sys\n" "sys.argv = ['notaninterpreterreally']\n" "from os.path import realpath, join, dirname"); PyRun_SimpleString(add_site_packages_dir); /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */ PyRun_SimpleString("sys.path = ['.'] + sys.path"); } PyRun_SimpleString( "class LogFile(object):\n" " def __init__(self):\n" " self.buffer = ''\n" " def write(self, s):\n" " s = self.buffer + s\n" " lines = s.split(\"\\n\")\n" " for l in lines[:-1]:\n" " androidembed.log(l)\n" " self.buffer = lines[-1]\n" " def flush(self):\n" " return\n" "sys.stdout = sys.stderr = LogFile()\n" "print('Android path', sys.path)\n" "import os\n" "print('os.environ is', os.environ)\n" "print('Android kivy bootstrap done. __name__ is', __name__)"); #if PY_MAJOR_VERSION < 3 PyRun_SimpleString("import site; print site.getsitepackages()\n"); #endif LOGP("AND: Ran string"); /* run it ! */ LOGP("Run user program, change dir and execute entrypoint"); /* Get the entrypoint, search the .pyo then .py */ char *dot = strrchr(env_entrypoint, '.'); if (dot <= 0) { LOGP("Invalid entrypoint, abort."); return -1; } if (strlen(env_entrypoint) > ENTRYPOINT_MAXLEN - 2) { LOGP("Entrypoint path is too long, try increasing ENTRYPOINT_MAXLEN."); return -1; } if (!strcmp(dot, ".pyo")) { if (!file_exists(env_entrypoint)) { /* fallback on .py */ strcpy(entrypoint, env_entrypoint); entrypoint[strlen(env_entrypoint) - 1] = '\0'; LOGP(entrypoint); if (!file_exists(entrypoint)) { LOGP("Entrypoint not found (.pyo, fallback on .py), abort"); return -1; } } else { strcpy(entrypoint, env_entrypoint); } } else if (!strcmp(dot, ".py")) { /* if .py is passed, check the pyo version first */ strcpy(entrypoint, env_entrypoint); entrypoint[strlen(env_entrypoint) + 1] = '\0'; entrypoint[strlen(env_entrypoint)] = 'o'; if (!file_exists(entrypoint)) { /* fallback on pure python version */ if (!file_exists(env_entrypoint)) { LOGP("Entrypoint not found (.py), abort."); return -1; } strcpy(entrypoint, env_entrypoint); } } else { LOGP("Entrypoint have an invalid extension (must be .py or .pyo), abort."); return -1; } // LOGP("Entrypoint is:"); // LOGP(entrypoint); fd = fopen(entrypoint, "r"); if (fd == NULL) { LOGP("Open the entrypoint failed"); LOGP(entrypoint); return -1; } /* run python ! */ ret = PyRun_SimpleFile(fd, entrypoint); if (PyErr_Occurred() != NULL) { ret = 1; PyErr_Print(); /* This exits with the right code if SystemExit. */ PyObject *f = PySys_GetObject("stdout"); if (PyFile_WriteString( "\n", f)) /* python2 used Py_FlushLine, but this no longer exists */ PyErr_Clear(); } /* close everything */ Py_Finalize(); fclose(fd); LOGP("Python for android ended."); return ret; }
//------------------------------------------------------------------------------------- bool Script::install(const wchar_t* pythonHomeDir, std::wstring pyPaths, const char* moduleName, COMPONENT_TYPE componentType) { std::wstring pySysPaths = SCRIPT_PATH; wchar_t* pwpySysResPath = strutil::char2wchar(const_cast<char*>(Resmgr::getSingleton().getPySysResPath().c_str())); strutil::kbe_replace(pySysPaths, L"../../res/", pwpySysResPath); pyPaths += pySysPaths; free(pwpySysResPath); #if KBE_PLATFORM == PLATFORM_WIN32 Py_SetPythonHome(const_cast<wchar_t*>(pythonHomeDir)); // 先设置python的环境变量 #else std::wstring fs = L";"; std::wstring rs = L":"; size_t pos = 0; while(true) { pos = pyPaths.find(fs, pos); if (pos == std::wstring::npos) break; pyPaths.replace(pos, fs.length(), rs); } Py_SetPath(pyPaths.c_str()); char* tmpchar = strutil::wchar2char(const_cast<wchar_t*>(pyPaths.c_str())); DEBUG_MSG(boost::format("Script::install: paths=%1%.\n") % tmpchar); free(tmpchar); #endif // Initialise python // Py_VerboseFlag = 2; Py_FrozenFlag = 1; // Warn if tab and spaces are mixed in indentation. // Py_TabcheckFlag = 1; Py_NoSiteFlag = 1; Py_IgnoreEnvironmentFlag = 1; Py_Initialize(); // python解释器的初始化 if (!Py_IsInitialized()) { ERROR_MSG("Script::install::Py_Initialize is failed!\n"); return false; } #if KBE_PLATFORM == PLATFORM_WIN32 PySys_SetPath(pyPaths.c_str()); #endif PyObject *m = PyImport_AddModule("__main__"); module_ = PyImport_AddModule(moduleName); // 添加一个脚本基础模块 if (module_ == NULL) return false; const char* componentName = COMPONENT_NAME_EX(componentType); if (PyModule_AddStringConstant(module_, "component", componentName)) { ERROR_MSG(boost::format("Script::init: Unable to set KBEngine.component to %1%\n") % componentName ); return false; } // 注册产生uuid方法到py APPEND_SCRIPT_MODULE_METHOD(module_, genUUID64, __py_genUUID64, METH_VARARGS, 0); if(!install_py_dlls()) { ERROR_MSG("Script::init: install_py_dlls() is failed!\n"); return false; } #ifndef KBE_SINGLE_THREADED s_pOurInitTimeModules = PyDict_Copy( PySys_GetObject( "modules" ) ); s_pMainThreadState = PyThreadState_Get(); s_defaultContext = s_pMainThreadState; PyEval_InitThreads(); KBEConcurrency::setMainThreadIdleFunctions( &Script::releaseLock, &Script::acquireLock ); #endif ScriptStdOutErr::installScript(NULL); // 安装py重定向模块 ScriptStdOutErrHook::installScript(NULL); static struct PyModuleDef moduleDesc = { PyModuleDef_HEAD_INIT, moduleName, "This module is created by KBEngine!", -1, NULL }; PyModule_Create(&moduleDesc); // 初始化基础模块 PyObject_SetAttrString(m, moduleName, module_); // 将模块对象加入main pyStdouterr_ = new ScriptStdOutErr(); // 重定向python输出 pyStdouterrHook_ = new ScriptStdOutErrHook(); if(!pyStdouterr_->install()){ // 安装py重定向脚本模块 ERROR_MSG("Script::install::pyStdouterr_->install() is failed!\n"); SCRIPT_ERROR_CHECK(); return false; } Pickler::initialize(); PyProfile::initialize(this); PyStruct::initialize(); Copy::initialize(); SCRIPT_ERROR_CHECK(); math::installModule("Math"); INFO_MSG("Script::install is successfully!\n"); return installExtraModule("KBExtra"); }
int AppMain() { std::wstring exe_dir; // Get exe's directory { wchar_t exe_path_buf[MAX_PATH + 1]; GetModuleFileName(NULL, exe_path_buf, MAX_PATH); exe_dir = exe_path_buf; size_t last_backslash_pos = exe_dir.find_last_of(L"\\/"); if (last_backslash_pos >= 0) { exe_dir = exe_dir.substr(0, last_backslash_pos); } else { exe_dir = L""; } } // Setup environment variable "PATH" { std::wstring env_path; wchar_t tmp_buf[1]; DWORD ret = GetEnvironmentVariable(L"PATH", tmp_buf, 0); if (ret > 0) { DWORD len = ret; wchar_t * buf = (wchar_t*)malloc((len + 1) * sizeof(wchar_t)); GetEnvironmentVariable(L"PATH", buf, (len + 1) * sizeof(wchar_t)); env_path = buf; free(buf); } env_path = exe_dir + L"/lib;" + env_path; SetEnvironmentVariable(L"PATH", env_path.c_str()); } // Python home { #if defined(_DEBUG) Py_SetPythonHome(PYTHON_INSTALL_PATH); #else Py_SetPythonHome(const_cast<wchar_t*>(exe_dir.c_str())); #endif //_DEBUG } // Python module search path { std::wstring python_path; python_path += exe_dir + L"/extension;"; #if defined(_DEBUG) python_path += exe_dir + L";"; python_path += exe_dir + L"/..;"; python_path += std::wstring(PYTHON_INSTALL_PATH) + L"\\Lib;"; python_path += std::wstring(PYTHON_INSTALL_PATH) + L"\\Lib\\site-packages;"; python_path += std::wstring(PYTHON_INSTALL_PATH) + L"\\DLLs;"; #else python_path += exe_dir + L"/library.zip;"; python_path += exe_dir + L"/lib;"; #endif Py_SetPath(python_path.c_str()); } // Initialization Py_Initialize(); // Setup sys.argv { wchar_t * cmdline = GetCommandLine(); int argc; wchar_t ** argv = CommandLineToArgvW(cmdline, &argc); PySys_SetArgv(argc, argv); LocalFree(argv); } // Execute python side main script { PyObject * module = PyImport_ImportModule("cfiler_main"); if (module == NULL) { PyErr_Print(); } Py_XDECREF(module); module = NULL; } // Termination Py_Finalize(); return 0; }
void setupPythonEnv(const char* argv0Param) { //Disable user sites as they could conflict with Natron bundled packages. //If this is set, Python won’t add the user site-packages directory to sys.path. //See https://www.python.org/dev/peps/pep-0370/ ProcInfo::putenv_wrapper("PYTHONNOUSERSITE", "1"); ++Py_NoUserSiteDirectory; // // set up paths, clear those that don't exist or are not valid // std::string binPath = ProcInfo::applicationDirPath(argv0Param); binPath = StrUtils::toNativeSeparators(binPath); #ifdef __NATRON_WIN32__ static std::string pythonHome = binPath + "\\.."; // must use static storage std::string pyPathZip = pythonHome + "\\lib\\python" NATRON_PY_VERSION_STRING_NO_DOT ".zip"; std::string pyPath = pythonHome + "\\lib\\python" NATRON_PY_VERSION_STRING; std::string pluginPath = binPath + "\\..\\Plugins"; #else # if defined(__NATRON_LINUX__) static std::string pythonHome = binPath + "/.."; // must use static storage # elif defined(__NATRON_OSX__) static std::string pythonHome = binPath+ "/../Frameworks/Python.framework/Versions/" NATRON_PY_VERSION_STRING; // must use static storage # else # error "unsupported platform" # endif std::string pyPathZip = pythonHome + "/lib/python" NATRON_PY_VERSION_STRING_NO_DOT ".zip"; std::string pyPath = pythonHome + "/lib/python" NATRON_PY_VERSION_STRING; std::string pluginPath = binPath + "/../Plugins"; #endif if ( !fileExists( StrUtils::fromNativeSeparators(pyPathZip) ) ) { # if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG) printf( "\"%s\" does not exist, not added to PYTHONPATH\n", pyPathZip.c_str() ); # endif pyPathZip.clear(); } if ( !dirExists( StrUtils::fromNativeSeparators(pyPath) ) ) { # if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG) printf( "\"%s\" does not exist, not added to PYTHONPATH\n", pyPath.c_str() ); # endif pyPath.clear(); } if ( !dirExists( StrUtils::fromNativeSeparators(pluginPath) ) ) { # if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG) printf( "\"%s\" does not exist, not added to PYTHONPATH\n", pluginPath.c_str() ); # endif pluginPath.clear(); } // PYTHONHOME is really useful if there's a python inside it if ( pyPathZip.empty() && pyPath.empty() ) { # if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG) printf( "dir \"%s\" does not exist or does not contain lib/python*, not setting PYTHONHOME\n", pythonHome.c_str() ); # endif pythonHome.clear(); } ///////////////////////////////////////// // Py_SetPythonHome ///////////////////////////////////////// // // Must be done before Py_Initialize (see doc of Py_Initialize) // // The argument should point to a zero-terminated character string in static storage whose contents will not change for the duration of the program’s execution if ( !pythonHome.empty() ) { # if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG) printf( "Py_SetPythonHome(\"%s\")\n", pythonHome.c_str() ); # endif # if PY_MAJOR_VERSION >= 3 // Python 3 static const std::wstring pythonHomeW = StrUtils::utf8_to_utf16(pythonHome); // must use static storage Py_SetPythonHome( const_cast<wchar_t*>( pythonHomeW.c_str() ) ); # else // Python 2 Py_SetPythonHome( const_cast<char*>( pythonHome.c_str() ) ); # endif } ///////////////////////////////////////// // PYTHONPATH and Py_SetPath ///////////////////////////////////////// // // note: to check the python path of a python install, execute: // python -c 'import sys,pprint; pprint.pprint( sys.path )' // // to build the python27.zip, cd to lib/python2.7, and generate the pyo and the zip file using: // // python -O -m compileall . // zip -r ../python27.zip *.py* bsddb compiler ctypes curses distutils email encodings hotshot idlelib importlib json logging multiprocessing pydoc_data sqlite3 unittest wsgiref xml // std::string pythonPath = ProcInfo::getenv_wrapper("PYTHONPATH"); //Add the Python distribution of Natron to the Python path std::vector<std::string> toPrepend; if ( !pyPathZip.empty() ) { toPrepend.push_back(pyPathZip); } if ( !pyPath.empty() ) { toPrepend.push_back(pyPath); } if ( !pluginPath.empty() ) { toPrepend.push_back(pluginPath); } #if defined(__NATRON_OSX__) && defined DEBUG // in debug mode, also prepend the local PySide directory // homebrew's pyside directory toPrepend.push_back("/usr/local/Cellar/pyside/1.2.2_1/lib/python" NATRON_PY_VERSION_STRING "/site-packages"); // macport's pyside directory toPrepend.push_back("/opt/local/Library/Frameworks/Python.framework/Versions/" NATRON_PY_VERSION_STRING "/lib/python" NATRON_PY_VERSION_STRING "/site-packages"); #endif if ( toPrepend.empty() ) { # if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG) printf("PYTHONPATH not modified\n"); # endif } else { # ifdef __NATRON_WIN32__ const char pathSep = ';'; # else const char pathSep = ':'; # endif std::string toPrependStr = StrUtils::join(toPrepend, pathSep); if (pythonPath.empty()) { pythonPath = toPrependStr; } else { pythonPath = toPrependStr + pathSep + pythonPath; } // qputenv on minw will just call putenv, but we want to keep the utf16 info, so we need to call _wputenv # if 0//def __NATRON_WIN32__ _wputenv_s(L"PYTHONPATH", StrUtils::utf8_to_utf16(pythonPath).c_str()); # else ProcInfo::putenv_wrapper( "PYTHONPATH", pythonPath.c_str() ); //Py_SetPath( pythonPathString.c_str() ); // does not exist in Python 2 # endif # if PY_MAJOR_VERSION >= 3 std::wstring pythonPathString = StrUtils::utf8_to_utf16(pythonPath); Py_SetPath( pythonPathString.c_str() ); // argument is copied internally, no need to use static storage # endif # if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG) printf( "PYTHONPATH set to %s\n", pythonPath.c_str() ); # endif } } // setupPythonEnv
/* int main(int argc, char **argv) { */ int main(int argc, char *argv[]) { char *env_argument = NULL; char *env_entrypoint = NULL; char *env_logname = NULL; char entrypoint[ENTRYPOINT_MAXLEN]; int ret = 0; FILE *fd; LOGP("Initializing Python for Android"); // Set a couple of built-in environment vars: setenv("P4A_BOOTSTRAP", bootstrap_name, 1); // env var to identify p4a to applications env_argument = getenv("ANDROID_ARGUMENT"); setenv("ANDROID_APP_PATH", env_argument, 1); env_entrypoint = getenv("ANDROID_ENTRYPOINT"); env_logname = getenv("PYTHON_NAME"); if (!getenv("ANDROID_UNPACK")) { /* ANDROID_UNPACK currently isn't set in services */ setenv("ANDROID_UNPACK", env_argument, 1); } if (env_logname == NULL) { env_logname = "python"; setenv("PYTHON_NAME", "python", 1); } // Set additional file-provided environment vars: LOGP("Setting additional env vars from p4a_env_vars.txt"); char env_file_path[256]; snprintf(env_file_path, sizeof(env_file_path), "%s/p4a_env_vars.txt", getenv("ANDROID_UNPACK")); FILE *env_file_fd = fopen(env_file_path, "r"); if (env_file_fd) { char* line = NULL; size_t len = 0; while (getline(&line, &len, env_file_fd) != -1) { if (strlen(line) > 0) { char *eqsubstr = strstr(line, "="); if (eqsubstr) { size_t eq_pos = eqsubstr - line; // Extract name: char env_name[256]; strncpy(env_name, line, sizeof(env_name)); env_name[eq_pos] = '\0'; // Extract value (with line break removed: char env_value[256]; strncpy(env_value, (char*)(line + eq_pos + 1), sizeof(env_value)); if (strlen(env_value) > 0 && env_value[strlen(env_value)-1] == '\n') { env_value[strlen(env_value)-1] = '\0'; if (strlen(env_value) > 0 && env_value[strlen(env_value)-1] == '\r') { // Also remove windows line breaks (\r\n) env_value[strlen(env_value)-1] = '\0'; } } // Set value: setenv(env_name, env_value, 1); } } } fclose(env_file_fd); } else { LOGP("Warning: no p4a_env_vars.txt found / failed to open!"); } LOGP("Changing directory to the one provided by ANDROID_ARGUMENT"); LOGP(env_argument); chdir(env_argument); #if PY_MAJOR_VERSION < 3 Py_NoSiteFlag=1; #endif #if PY_MAJOR_VERSION < 3 Py_SetProgramName("android_python"); #else Py_SetProgramName(L"android_python"); #endif #if PY_MAJOR_VERSION >= 3 /* our logging module for android */ PyImport_AppendInittab("androidembed", initandroidembed); #endif LOGP("Preparing to initialize python"); // Set up the python path char paths[256]; char crystax_python_dir[256]; snprintf(crystax_python_dir, 256, "%s/crystax_python", getenv("ANDROID_UNPACK")); char python_bundle_dir[256]; snprintf(python_bundle_dir, 256, "%s/_python_bundle", getenv("ANDROID_UNPACK")); if (dir_exists(crystax_python_dir) || dir_exists(python_bundle_dir)) { if (dir_exists(crystax_python_dir)) { LOGP("crystax_python exists"); snprintf(paths, 256, "%s/stdlib.zip:%s/modules", crystax_python_dir, crystax_python_dir); } if (dir_exists(python_bundle_dir)) { LOGP("_python_bundle dir exists"); snprintf(paths, 256, "%s/stdlib.zip:%s/modules", python_bundle_dir, python_bundle_dir); } LOGP("calculated paths to be..."); LOGP(paths); #if PY_MAJOR_VERSION >= 3 wchar_t *wchar_paths = Py_DecodeLocale(paths, NULL); Py_SetPath(wchar_paths); #endif LOGP("set wchar paths..."); } else { // We do not expect to see crystax_python any more, so no point // reminding the user about it. If it does exist, we'll have // logged it earlier. LOGP("_python_bundle does not exist"); } Py_Initialize(); #if PY_MAJOR_VERSION < 3 // Can't Py_SetPath in python2 but we can set PySys_SetPath, which must // be applied after Py_Initialize rather than before like Py_SetPath #if PY_MICRO_VERSION >= 15 // Only for python native-build PySys_SetPath(paths); #endif PySys_SetArgv(argc, argv); #endif LOGP("Initialized python"); /* ensure threads will work. */ LOGP("AND: Init threads"); PyEval_InitThreads(); #if PY_MAJOR_VERSION < 3 initandroidembed(); #endif PyRun_SimpleString("import androidembed\nandroidembed.log('testing python " "print redirection')"); /* inject our bootstrap code to redirect python stdin/stdout * replace sys.path with our path */ PyRun_SimpleString("import sys, posix\n"); if (dir_exists("lib")) { /* If we built our own python, set up the paths correctly. * This is only the case if we are using the python2legacy recipe */ LOGP("Setting up python from ANDROID_APP_PATH"); PyRun_SimpleString("private = posix.environ['ANDROID_APP_PATH']\n" "argument = posix.environ['ANDROID_ARGUMENT']\n" "sys.path[:] = [ \n" " private + '/lib/python27.zip', \n" " private + '/lib/python2.7/', \n" " private + '/lib/python2.7/lib-dynload/', \n" " private + '/lib/python2.7/site-packages/', \n" " argument ]\n"); } char add_site_packages_dir[256]; if (dir_exists(crystax_python_dir)) { snprintf(add_site_packages_dir, 256, "sys.path.append('%s/site-packages')", crystax_python_dir); PyRun_SimpleString("import sys\n" "sys.argv = ['notaninterpreterreally']\n" "from os.path import realpath, join, dirname"); PyRun_SimpleString(add_site_packages_dir); /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */ PyRun_SimpleString("sys.path = ['.'] + sys.path"); } if (dir_exists(python_bundle_dir)) { snprintf(add_site_packages_dir, 256, "sys.path.append('%s/site-packages')", python_bundle_dir); PyRun_SimpleString("import sys\n" "sys.argv = ['notaninterpreterreally']\n" "from os.path import realpath, join, dirname"); PyRun_SimpleString(add_site_packages_dir); /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */ PyRun_SimpleString("sys.path = ['.'] + sys.path"); } PyRun_SimpleString( "class LogFile(object):\n" " def __init__(self):\n" " self.buffer = ''\n" " def write(self, s):\n" " s = self.buffer + s\n" " lines = s.split(\"\\n\")\n" " for l in lines[:-1]:\n" " androidembed.log(l)\n" " self.buffer = lines[-1]\n" " def flush(self):\n" " return\n" "sys.stdout = sys.stderr = LogFile()\n" "print('Android path', sys.path)\n" "import os\n" "print('os.environ is', os.environ)\n" "print('Android kivy bootstrap done. __name__ is', __name__)"); #if PY_MAJOR_VERSION < 3 PyRun_SimpleString("import site; print site.getsitepackages()\n"); #endif LOGP("AND: Ran string"); /* run it ! */ LOGP("Run user program, change dir and execute entrypoint"); /* Get the entrypoint, search the .pyo then .py */ char *dot = strrchr(env_entrypoint, '.'); #if PY_MAJOR_VERSION > 2 char *ext = ".pyc"; #else char *ext = ".pyo"; #endif if (dot <= 0) { LOGP("Invalid entrypoint, abort."); return -1; } if (strlen(env_entrypoint) > ENTRYPOINT_MAXLEN - 2) { LOGP("Entrypoint path is too long, try increasing ENTRYPOINT_MAXLEN."); return -1; } if (!strcmp(dot, ext)) { if (!file_exists(env_entrypoint)) { /* fallback on .py */ strcpy(entrypoint, env_entrypoint); entrypoint[strlen(env_entrypoint) - 1] = '\0'; LOGP(entrypoint); if (!file_exists(entrypoint)) { LOGP("Entrypoint not found (.pyc/.pyo, fallback on .py), abort"); return -1; } } else { strcpy(entrypoint, env_entrypoint); } } else if (!strcmp(dot, ".py")) { /* if .py is passed, check the pyo version first */ strcpy(entrypoint, env_entrypoint); entrypoint[strlen(env_entrypoint) + 1] = '\0'; #if PY_MAJOR_VERSION > 2 entrypoint[strlen(env_entrypoint)] = 'c'; #else entrypoint[strlen(env_entrypoint)] = 'o'; #endif if (!file_exists(entrypoint)) { /* fallback on pure python version */ if (!file_exists(env_entrypoint)) { LOGP("Entrypoint not found (.py), abort."); return -1; } strcpy(entrypoint, env_entrypoint); } } else { LOGP("Entrypoint have an invalid extension (must be .py or .pyc/.pyo), abort."); return -1; } // LOGP("Entrypoint is:"); // LOGP(entrypoint); fd = fopen(entrypoint, "r"); if (fd == NULL) { LOGP("Open the entrypoint failed"); LOGP(entrypoint); return -1; } /* run python ! */ ret = PyRun_SimpleFile(fd, entrypoint); fclose(fd); if (PyErr_Occurred() != NULL) { ret = 1; PyErr_Print(); /* This exits with the right code if SystemExit. */ PyObject *f = PySys_GetObject("stdout"); if (PyFile_WriteString( "\n", f)) /* python2 used Py_FlushLine, but this no longer exists */ PyErr_Clear(); } LOGP("Python for android ended."); /* Shut down: since regular shutdown causes issues sometimes (seems to be an incomplete shutdown breaking next launch) we'll use sys.exit(ret) to shutdown, since that one works. Reference discussion: https://github.com/kivy/kivy/pull/6107#issue-246120816 */ char terminatecmd[256]; snprintf( terminatecmd, sizeof(terminatecmd), "import sys; sys.exit(%d)\n", ret ); PyRun_SimpleString(terminatecmd); /* This should never actually be reached, but we'll leave the clean-up * here just to be safe. */ #if PY_MAJOR_VERSION < 3 Py_Finalize(); LOGP("Unexpectedly reached Py_FinalizeEx(), but was successful."); #else if (Py_FinalizeEx() != 0) // properly check success on Python 3 LOGP("Unexpectedly reached Py_FinalizeEx(), and got error!"); else LOGP("Unexpectedly reached Py_FinalizeEx(), but was successful."); #endif return ret; }
/* int main(int argc, char **argv) { */ int main(int argc, char *argv[]) { char *env_argument = NULL; int ret = 0; FILE *fd; /* AND: Several filepaths are hardcoded here, these must be made configurable */ /* AND: P4A uses env vars...not sure what's best */ LOG("Initialize Python for Android"); /* env_argument = "/data/data/org.kivy.android/files"; */ env_argument = getenv("ANDROID_ARGUMENT"); /* setenv("ANDROID_APP_PATH", env_argument, 1); */ /* setenv("ANDROID_ARGUMENT", env_argument, 1); */ /* setenv("ANDROID_PRIVATE", env_argument, 1); */ /* setenv("ANDROID_APP_PATH", env_argument, 1); */ /* setenv("PYTHONHOME", env_argument, 1); */ /* setenv("PYTHONPATH", "/data/data/org.kivy.android/files:/data/data/org.kivy.android/files/lib", 1); */ /* LOG("AND: Set env vars"); */ /* LOG(argv[0]); */ /* LOG("AND: That was argv 0"); */ //setenv("PYTHONVERBOSE", "2", 1); LOG("Changing directory to the one provided by ANDROID_ARGUMENT"); LOG(env_argument); chdir(env_argument); Py_SetProgramName(L"android_python"); #if PY_MAJOR_VERSION >= 3 /* our logging module for android */ PyImport_AppendInittab("androidembed", initandroidembed); #endif LOG("Preparing to initialize python"); if (dir_exists("crystax_python/")) { LOG("crystax_python exists"); char paths[256]; snprintf(paths, 256, "%s/crystax_python/stdlib.zip:%s/crystax_python/modules", env_argument, env_argument); /* snprintf(paths, 256, "%s/stdlib.zip:%s/modules", env_argument, env_argument); */ LOG("calculated paths to be..."); LOG(paths); #if PY_MAJOR_VERSION >= 3 wchar_t* wchar_paths = Py_DecodeLocale(paths, NULL); Py_SetPath(wchar_paths); #else char* wchar_paths = paths; LOG("Can't Py_SetPath in python2, so crystax python2 doesn't work yet"); exit(1); #endif LOG("set wchar paths..."); } else { LOG("crystax_python does not exist");} Py_Initialize(); #if PY_MAJOR_VERSION < 3 PySys_SetArgv(argc, argv); #endif LOG("Initialized python"); /* ensure threads will work. */ LOG("AND: Init threads"); PyEval_InitThreads(); #if PY_MAJOR_VERSION < 3 initandroidembed(); #endif PyRun_SimpleString("import androidembed\nandroidembed.log('testing python print redirection')"); /* inject our bootstrap code to redirect python stdin/stdout * replace sys.path with our path */ PyRun_SimpleString("import sys, posix\n"); if (dir_exists("lib")) { /* If we built our own python, set up the paths correctly */ LOG("Setting up python from ANDROID_PRIVATE"); PyRun_SimpleString( "private = posix.environ['ANDROID_PRIVATE']\n" \ "argument = posix.environ['ANDROID_ARGUMENT']\n" \ "sys.path[:] = [ \n" \ " private + '/lib/python27.zip', \n" \ " private + '/lib/python2.7/', \n" \ " private + '/lib/python2.7/lib-dynload/', \n" \ " private + '/lib/python2.7/site-packages/', \n" \ " argument ]\n"); } if (dir_exists("crystax_python")) { char add_site_packages_dir[256]; snprintf(add_site_packages_dir, 256, "sys.path.append('%s/crystax_python/site-packages')", env_argument); PyRun_SimpleString( "import sys\n" \ "sys.argv = ['notaninterpreterreally']\n" \ "from os.path import realpath, join, dirname"); PyRun_SimpleString(add_site_packages_dir); /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */ PyRun_SimpleString("sys.path = ['.'] + sys.path"); } PyRun_SimpleString( "class LogFile(object):\n" \ " def __init__(self):\n" \ " self.buffer = ''\n" \ " def write(self, s):\n" \ " s = self.buffer + s\n" \ " lines = s.split(\"\\n\")\n" \ " for l in lines[:-1]:\n" \ " androidembed.log(l)\n" \ " self.buffer = lines[-1]\n" \ " def flush(self):\n" \ " return\n" \ "sys.stdout = sys.stderr = LogFile()\n" \ "print('Android path', sys.path)\n" \ "import os\n" \ "print('os.environ is', os.environ)\n" \ "print('Android kivy bootstrap done. __name__ is', __name__)"); /* PyRun_SimpleString( */ /* "import sys, posix\n" \ */ /* "private = posix.environ['ANDROID_PRIVATE']\n" \ */ /* "argument = posix.environ['ANDROID_ARGUMENT']\n" \ */ /* "sys.path[:] = [ \n" \ */ /* " private + '/lib/python27.zip', \n" \ */ /* " private + '/lib/python2.7/', \n" \ */ /* " private + '/lib/python2.7/lib-dynload/', \n" \ */ /* " private + '/lib/python2.7/site-packages/', \n" \ */ /* " argument ]\n" \ */ /* "import androidembed\n" \ */ /* "class LogFile(object):\n" \ */ /* " def __init__(self):\n" \ */ /* " self.buffer = ''\n" \ */ /* " def write(self, s):\n" \ */ /* " s = self.buffer + s\n" \ */ /* " lines = s.split(\"\\n\")\n" \ */ /* " for l in lines[:-1]:\n" \ */ /* " androidembed.log(l)\n" \ */ /* " self.buffer = lines[-1]\n" \ */ /* " def flush(self):\n" \ */ /* " return\n" \ */ /* "sys.stdout = sys.stderr = LogFile()\n" \ */ /* "import site; print site.getsitepackages()\n"\ */ /* "print 'Android path', sys.path\n" \ */ /* "print 'Android kivy bootstrap done. __name__ is', __name__"); */ LOG("AND: Ran string"); /* run it ! */ LOG("Run user program, change dir and execute main.py"); /* search the initial main.py */ char *main_py = "main.pyo"; if ( file_exists(main_py) == 0 ) { if ( file_exists("main.py") ) main_py = "main.py"; else main_py = NULL; } if ( main_py == NULL ) { LOG("No main.pyo / main.py found."); return -1; } fd = fopen(main_py, "r"); if ( fd == NULL ) { LOG("Open the main.py(o) failed"); return -1; } /* run python ! */ ret = PyRun_SimpleFile(fd, main_py); if (PyErr_Occurred() != NULL) { ret = 1; PyErr_Print(); /* This exits with the right code if SystemExit. */ PyObject *f = PySys_GetObject("stdout"); if (PyFile_WriteString("\n", f)) /* python2 used Py_FlushLine, but this no longer exists */ PyErr_Clear(); } /* close everything */ Py_Finalize(); fclose(fd); LOG("Python for android ended."); return ret; }
//--------------------------------------------------------------------------------- // Initializes python. //--------------------------------------------------------------------------------- bool CPythonManager::Initialize( void ) { // Construct a path to the python engine directory. char szPythonHome[MAX_GAME_PATH]; V_snprintf(szPythonHome, MAX_GAME_PATH, "%s/Python3", g_GamePaths.GetSPDir()); V_FixSlashes(szPythonHome); DevMsg(1, "[SP] Python home path set to %s\n", szPythonHome); // Convert to wide char for python. wchar_t wszPythonHome[1024]; V_strtowcs(szPythonHome, -1, wszPythonHome, 1024); // Set that as the python home directory. Py_SetPythonHome(wszPythonHome); Py_SetProgramName(wszPythonHome); Py_SetPath(wszPythonHome); // Initialize python and its namespaces. Py_Initialize(); // Print some information DevMsg(1, "Python version %s initialized!\n", Py_GetVersion()); // Make sure sys is imported. PyRun_SimpleString("import sys"); // Add the Python API path. AddToSysPath("/packages/source-python"); // Add operating system specific paths. #if defined(WIN32) AddToSysPath("/Python3/plat-win"); #else AddToSysPath("/Python3/plat-linux"); // We've got a bunch of linux shared objects here we need to load. AddToSysPath("/Python3/lib-dynload"); #endif // Site packages for any extra packages... AddToSysPath("/packages/site-packages"); // Add the custom packages path. AddToSysPath("/packages/custom"); // And of course, the plugins directory for script imports. AddToSysPath("/plugins"); // Initialize all converters InitConverters(); // Initialize all submodules modulsp_init(); // Import the main module file. DevMsg(1, "[SP] Importing main module..\n"); BEGIN_BOOST_PY() python::import("__init__"); END_BOOST_PY_NORET(); // Noret because we have more stuff to do after this import. DevMsg(0, "[Source.Python] Loaded successfully.\n"); return true; }
//------------------------------------------------------------------------------------- bool Script::install(const wchar_t* pythonHomeDir, std::wstring pyPaths, const char* moduleName, COMPONENT_TYPE componentType) { std::wstring pySysPaths = SCRIPT_PATH; wchar_t* pwpySysResPath = strutil::char2wchar(const_cast<char*>(Resmgr::getSingleton().getPySysResPath().c_str())); strutil::kbe_replace(pySysPaths, L"../../res/", pwpySysResPath); pyPaths += pySysPaths; free(pwpySysResPath); // 先设置python的环境变量 Py_SetPythonHome(const_cast<wchar_t*>(pythonHomeDir)); #if KBE_PLATFORM != PLATFORM_WIN32 std::wstring fs = L";"; std::wstring rs = L":"; size_t pos = 0; while(true) { pos = pyPaths.find(fs, pos); if (pos == std::wstring::npos) break; pyPaths.replace(pos, fs.length(), rs); } char* tmpchar = strutil::wchar2char(const_cast<wchar_t*>(pyPaths.c_str())); DEBUG_MSG(fmt::format("Script::install(): paths={}.\n", tmpchar)); free(tmpchar); #endif // Initialise python // Py_VerboseFlag = 2; Py_FrozenFlag = 1; // Warn if tab and spaces are mixed in indentation. // Py_TabcheckFlag = 1; Py_NoSiteFlag = 1; Py_IgnoreEnvironmentFlag = 1; Py_SetPath(pyPaths.c_str()); // python解释器的初始化 Py_Initialize(); if (!Py_IsInitialized()) { ERROR_MSG("Script::install(): Py_Initialize is failed!\n"); return false; } PyObject *m = PyImport_AddModule("__main__"); // 添加一个脚本基础模块 module_ = PyImport_AddModule(moduleName); if (module_ == NULL) return false; const char* componentName = COMPONENT_NAME_EX(componentType); if (PyModule_AddStringConstant(module_, "component", componentName)) { ERROR_MSG(fmt::format("Script::install(): Unable to set KBEngine.component to {}\n", componentName)); return false; } // 注册产生uuid方法到py APPEND_SCRIPT_MODULE_METHOD(module_, genUUID64, __py_genUUID64, METH_VARARGS, 0); if(!install_py_dlls()) { ERROR_MSG("Script::install(): install_py_dlls() is failed!\n"); return false; } // 安装py重定向模块 ScriptStdOut::installScript(NULL); ScriptStdErr::installScript(NULL); /* static struct PyModuleDef moduleDesc = { PyModuleDef_HEAD_INIT, moduleName, "This module is created by KBEngine!", -1, NULL }; // 初始化基础模块 PyModule_Create(&moduleDesc); */ // 将模块对象加入main PyObject_SetAttrString(m, moduleName, module_); PyObject_SetAttrString(module_, "__doc__", PyUnicode_FromString("This module is created by KBEngine!")); // 重定向python输出 pyStdouterr_ = new ScriptStdOutErr(); // 安装py重定向脚本模块 if(!pyStdouterr_->install()){ ERROR_MSG("Script::install::pyStdouterr_->install() is failed!\n"); delete pyStdouterr_; SCRIPT_ERROR_CHECK(); return false; } PyGC::initialize(); Pickler::initialize(); PyProfile::initialize(this); PyStruct::initialize(); Copy::initialize(); SCRIPT_ERROR_CHECK(); math::installModule("Math"); INFO_MSG(fmt::format("Script::install(): is successfully, Python=({})!\n", Py_GetVersion())); return installExtraModule("KBExtra"); }
int init_with_instance(HMODULE hmod_exe, char *frozen) { int rc = 0; HMODULE hmod_pydll; /* Py_NoSiteFlag = 1; /* Suppress 'import site' */ /* Py_InspectFlag = 1; /* Needed to determine whether to exit at SystemExit */ calc_dirname(hmod_exe); // wprintf(L"modulename %s\n", modulename); // wprintf(L"dirname %s\n", dirname); if (!locate_script(hmod_exe)) { SystemError(-1, "FATAL ERROR: Could not locate script"); // printf("FATAL ERROR locating script\n"); return -1; } hmod_pydll = load_pythondll(); if (hmod_pydll == NULL) { SystemError(-1, "FATAL ERROR: Could not load python library"); // printf("FATAL Error: could not load python library\n"); return -1; } if (PythonLoaded(hmod_pydll) < 0) { SystemError(-1, "FATAL ERROR: Failed to load some Python symbols"); // printf("FATAL Error: failed to load some Python symbols\n"); return -1; } set_vars(hmod_pydll); /* _memimporter contains the magic which allows to load dlls from memory, without unpacking them to the file-system. It is compiled into all the exe-stubs. */ PyImport_AppendInittab("_memimporter", PyInit__memimporter); /* Start the ball rolling. */ Py_SetProgramName(modulename); Py_SetPath(libfilename); Py_Initialize(); /* Set sys.frozen so apps that care can tell. If the caller did pass NULL, sys.frozen will be set to 'True'. If a string is passed this is used as the frozen attribute. run.c passes "console_exe", run_w.c passes "windows_exe", run_dll.c passes "dll" This falls apart when you consider that in some cases, a single process may end up with two py2exe generated apps - but still, we reset frozen to the correct 'current' value for the newly initializing app. */ if (frozen == NULL) PySys_SetObject("frozen", PyBool_FromLong(1)); else { PyObject *o = PyUnicode_FromString(frozen); if (o) { PySys_SetObject("frozen", o); Py_DECREF(o); } } return rc; }
//--------------------------------------------------------------------------------- // Initializes python. //--------------------------------------------------------------------------------- bool CPythonManager::Initialize( void ) { // Construct a path to the python engine directory. char szPythonHome[MAX_PATH_LENGTH]; V_snprintf(szPythonHome, MAX_PATH_LENGTH, "%s/Python3", GetSourcePythonDir()); V_FixSlashes(szPythonHome); DevMsg(1, MSG_PREFIX "Python home path set to %s\n", szPythonHome); // Convert to wide char for python. wchar_t wszPythonHome[MAX_PATH_LENGTH]; V_strtowcs(szPythonHome, -1, wszPythonHome, MAX_PATH_LENGTH); // Set that as the python home directory. Py_SetPythonHome(wszPythonHome); Py_SetProgramName(wszPythonHome); Py_SetPath(wszPythonHome); // Initialize python and its namespaces. Py_Initialize(); // Print some information DevMsg(1, MSG_PREFIX "Python version %s initialized!\n", Py_GetVersion()); // Set sys.argv and update sys.path DevMsg(1, MSG_PREFIX "Setting sys.argv...\n"); ICommandLine* pCommandLine = CommandLine(); int iParamCount = pCommandLine->ParmCount(); wchar_t** argv = new wchar_t*[iParamCount]; for (int i=0; i < iParamCount; i++) { const char* szParam = pCommandLine->GetParm(i); int iParamLength = strlen(szParam); wchar_t* wszParam = new wchar_t[iParamLength+1]; // Not sure what's wrong with V_strtowcs, but it seems like it // doesn't convert the string correctly on Linux mbstowcs(wszParam, szParam, iParamLength+1); argv[i] = wszParam; } PySys_SetArgv(iParamCount, argv); // Make sure sys is imported. PyRun_SimpleString("import sys"); // Add the Python API path. AddToSysPath("/packages/source-python"); // Add operating system specific paths. #if defined(WIN32) AddToSysPath("/Python3/plat-win"); #else AddToSysPath("/Python3/plat-linux"); // We've got a bunch of linux shared objects here we need to load. AddToSysPath("/Python3/lib-dynload"); #endif // Site packages for any extra packages... AddToSysPath("/packages/site-packages"); // Add the custom packages path. AddToSysPath("/packages/custom"); // And of course, the plugins directory for script imports. AddToSysPath("/plugins"); // Initialize all converters InitConverters(); // Initialize all submodules if (!modulsp_init()) { Msg(MSG_PREFIX "Failed to initialize internal modules.\n"); return false; } // Import the main module file. DevMsg(1, MSG_PREFIX "Loading main module...\n"); try { python::import("__init__").attr("load")(); } catch( ... ) { PyErr_Print(); PyErr_Clear(); Msg(MSG_PREFIX "Failed to load the main module.\n"); return false; } return true; }