diff --git a/src/Main/FreeCADGuiPy.cpp b/src/Main/FreeCADGuiPy.cpp index 420e5aea8d..cd4d850a67 100644 --- a/src/Main/FreeCADGuiPy.cpp +++ b/src/Main/FreeCADGuiPy.cpp @@ -319,7 +319,11 @@ QWidget* setupMainWindow() return Gui::getMainWindow(); } +#if PY_MAJOR_VERSION >= 3 +PyMODINIT_FUNC PyInit_FreeCADGui() +#else PyMODINIT_FUNC initFreeCADGui() +#endif { try { Base::Interpreter().loadModule("FreeCAD"); @@ -327,7 +331,13 @@ PyMODINIT_FUNC initFreeCADGui() App::Application::Config()["SplashScreen"] = "freecadsplash"; App::Application::Config()["CopyrightInfo"] = "\xc2\xa9 Juergen Riegel, Werner Mayer, Yorik van Havre 2001-2017\n"; Gui::Application::initApplication(); - Py_InitModule("FreeCADGui", FreeCADGui_methods); +#if PY_MAJOR_VERSION >= 3 + static struct PyModuleDef FreeCADGuiModuleDef = {PyModuleDef_HEAD_INIT,"FreeCADGui", "FreeCAD GUI module\n", -1, FreeCADGui_methods}; + PyObject* module = PyModule_Create(&FreeCADGuiModuleDef); + return module; +#else + Py_InitModule3("FreeCADGui", FreeCADGui_methods, "FreeCAD GUI module\n"); +#endif } catch (const Base::Exception& e) { PyErr_Format(PyExc_ImportError, "%s\n", e.what()); @@ -335,5 +345,8 @@ PyMODINIT_FUNC initFreeCADGui() catch (...) { PyErr_SetString(PyExc_ImportError, "Unknown runtime error occurred"); } +#if PY_MAJOR_VERSION >= 3 + return 0; +#endif } diff --git a/src/Main/MainGui.cpp b/src/Main/MainGui.cpp index 62f4c2f766..e3019495e2 100644 --- a/src/Main/MainGui.cpp +++ b/src/Main/MainGui.cpp @@ -201,7 +201,11 @@ int main( int argc, char ** argv ) "Python is searching for its files in the following directories:\n%3\n\n" "Python version information:\n%4\n") .arg(appName).arg(QString::fromUtf8(e.what())) +#if PY_MAJOR_VERSION >= 3 + .arg(QString::fromUtf8(Py_EncodeLocale(Py_GetPath(),NULL))).arg(QString::fromLatin1(Py_GetVersion())); +#else .arg(QString::fromUtf8(Py_GetPath())).arg(QString::fromLatin1(Py_GetVersion())); +#endif const char* pythonhome = getenv("PYTHONHOME"); if (pythonhome) { msg += QObject::tr("\nThe environment variable PYTHONHOME is set to '%1'.") diff --git a/src/Main/MainPy.cpp b/src/Main/MainPy.cpp index ccfc6b8dde..1f2070e4cc 100644 --- a/src/Main/MainPy.cpp +++ b/src/Main/MainPy.cpp @@ -85,25 +85,25 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserv #else # define MainExport #endif - -extern "C" +#if PY_MAJOR_VERSION >= 3 +PyMODINIT_FUNC PyInit_FreeCAD() +#else +PyMODINIT_FUNC initFreeCAD() +#endif { - void MainExport initFreeCAD() { + // Init phase =========================================================== + App::Application::Config()["ExeName"] = "FreeCAD"; + App::Application::Config()["ExeVendor"] = "FreeCAD"; + App::Application::Config()["AppDataSkipVendor"] = "true"; - // Init phase =========================================================== - App::Application::Config()["ExeName"] = "FreeCAD"; - App::Application::Config()["ExeVendor"] = "FreeCAD"; - App::Application::Config()["AppDataSkipVendor"] = "true"; - - - int argc=1; - char** argv; - argv = (char**)malloc(sizeof(char*)* (argc+1)); + int argc=1; + char** argv; + argv = (char**)malloc(sizeof(char*)* (argc+1)); #if defined(FC_OS_WIN32) - argv[0] = (char*)malloc(MAX_PATH); - strncpy(argv[0],App::Application::Config()["AppHomePath"].c_str(),MAX_PATH); - argv[0][MAX_PATH-1] = '\0'; // ensure null termination + argv[0] = (char*)malloc(MAX_PATH); + strncpy(argv[0],App::Application::Config()["AppHomePath"].c_str(),MAX_PATH); + argv[0][MAX_PATH-1] = '\0'; // ensure null termination #elif defined(FC_OS_CYGWIN) HMODULE hModule = GetModuleHandle("FreeCAD.dll"); char szFileName [MAX_PATH]; @@ -116,11 +116,19 @@ extern "C" putenv("LC_ALL=C"); // get whole path of the library Dl_info info; +#if PY_MAJOR_VERSION >= 3 + int ret = dladdr((void*)PyInit_FreeCAD, &info); +#else int ret = dladdr((void*)initFreeCAD, &info); +#endif if ((ret == 0) || (!info.dli_fname)) { free(argv); PyErr_SetString(PyExc_ImportError, "Cannot get path of the FreeCAD module!"); +#if PY_MAJOR_VERSION >= 3 + return 0; +#else return; +#endif } argv[0] = (char*)malloc(PATH_MAX); @@ -196,33 +204,42 @@ extern "C" } // end if ( PyList_Check(pySysPath) ) { if (buf == NULL) { - PyErr_SetString(PyExc_ImportError, "Cannot get path of the FreeCAD module!"); - return; - } + PyErr_SetString(PyExc_ImportError, "Cannot get path of the FreeCAD module!"); +#if PY_MAJOR_VERSION >= 3 + return 0; +#else + return; +#endif + } argv[0] = buf; #else # error "Implement: Retrieve the path of the module for your platform." #endif - argv[argc] = 0; + argv[argc] = 0; - try { - // Inits the Application - App::Application::init(argc,argv); - } - catch (const Base::Exception& e) { - std::string appName = App::Application::Config()["ExeName"]; - std::stringstream msg; - msg << "While initializing " << appName << " the following exception occurred: '" - << e.what() << "'\n\n"; - msg << "\nPlease contact the application's support team for more information.\n\n"; - printf("Initialization of %s failed:\n%s", appName.c_str(), msg.str().c_str()); - } + try { + // Inits the Application + App::Application::init(argc,argv); + } + catch (const Base::Exception& e) { + std::string appName = App::Application::Config()["ExeName"]; + std::stringstream msg; + msg << "While initializing " << appName << " the following exception occurred: '" + << e.what() << "'\n\n"; + msg << "\nPlease contact the application's support team for more information.\n\n"; + printf("Initialization of %s failed:\n%s", appName.c_str(), msg.str().c_str()); + } - free(argv[0]); - free(argv); + free(argv[0]); + free(argv); - return; - } //InitFreeCAD.... -} // extern "C" +#if PY_MAJOR_VERSION >= 3 + PyObject* module = _PyImport_FindBuiltin("FreeCAD"); + if (!module) { + PyErr_SetString(PyExc_ImportError, "Failed to load FreeCAD module!"); + } + return module; +#endif +}