workaround for bug in VS 2013 that occurs at Python init time

This commit is contained in:
wmayer
2018-04-15 19:05:06 +02:00
parent 0c394ff352
commit 1b5995d787
3 changed files with 38 additions and 1 deletions

View File

@@ -485,6 +485,12 @@ const char* InterpreterSingleton::init(int argc,char *argv[])
#else
Py_SetProgramName(argv[0]);
#endif
// There is a serious bug in VS from 2010 until 2013 where the file descriptor for stdin, stdout or stderr
// returns a valid value for GUI applications (i.e. subsytem = Windows) where it shouldn't.
// This causes Python to fail during initialization.
// A workaround is to use freopen on stdin, stdout and stderr. See the class Redirection inside main()
// https://bugs.python.org/issue17797#msg197474
//
Py_Initialize();
PyEval_InitThreads();
#if PY_MAJOR_VERSION >= 3
@@ -505,6 +511,7 @@ const char* InterpreterSingleton::init(int argc,char *argv[])
this->_global = PyEval_SaveThread();
}
#if PY_MAJOR_VERSION >= 3
PyGILStateLocker lock;
#if PY_MINOR_VERSION >= 5
return Py_EncodeLocale(Py_GetPath(),NULL);
#else

View File

@@ -1032,6 +1032,7 @@ bool Application::activateWorkbench(const char* name)
if (oldWb && oldWb->name() == name)
return false; // already active
Base::PyGILStateLocker lock;
// we check for the currently active workbench and call its 'Deactivated'
// method, if available
PyObject* pcOldWorkbench = 0;
@@ -1040,7 +1041,6 @@ bool Application::activateWorkbench(const char* name)
}
// get the python workbench object from the dictionary
Base::PyGILStateLocker lock;
PyObject* pcWorkbench = 0;
pcWorkbench = PyDict_GetItemString(_pcWorkbenchDictionary, name);
// test if the workbench exists

View File

@@ -71,6 +71,29 @@ const char sBanner[] = "\xc2\xa9 Juergen Riegel, Werner Mayer, Yorik van Havre 2
void InitMiniDumpWriter(const std::string&);
#endif
class Redirection
{
public:
Redirection(FILE* f)
: fi(Base::FileInfo::getTempFileName()), file(f)
{
#ifdef WIN32
_wfreopen(fi.toStdWString().c_str(),L"w",file);
#else
freopen(fi.filePath().c_str(),"w",file);
#endif
}
~Redirection()
{
fclose(file);
fi.deleteFile();
}
private:
Base::FileInfo fi;
FILE* file;
};
#if defined (FC_OS_LINUX) || defined(FC_OS_BSD)
QString myDecoderFunc(const QByteArray &localFileName)
{
@@ -133,6 +156,13 @@ int main( int argc, char ** argv )
}
#endif
#if PY_MAJOR_VERSION >= 3
#if defined(_MSC_VER) && _MSC_VER <= 1800
// See InterpreterSingleton::init
Redirection out(stdout), err(stderr), inp(stdin);
#endif
#endif // PY_MAJOR_VERSION
// Name and Version of the Application
App::Application::Config()["ExeName"] = "FreeCAD";
App::Application::Config()["ExeVendor"] = "FreeCAD";