FreeCAD

Форк
0
/
MainPy.cpp 
203 строки · 7.1 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de>              *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This program is free software; you can redistribute it and/or modify  *
7
 *   it under the terms of the GNU Library General Public License (LGPL)   *
8
 *   as published by the Free Software Foundation; either version 2 of     *
9
 *   the License, or (at your option) any later version.                   *
10
 *   for detail see the LICENCE text file.                                 *
11
 *                                                                         *
12
 *   FreeCAD is distributed in the hope that it will be useful,            *
13
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15
 *   GNU Library General Public License for more details.                  *
16
 *                                                                         *
17
 *   You should have received a copy of the GNU Library General Public     *
18
 *   License along with FreeCAD; if not, write to the Free Software        *
19
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
20
 *   USA                                                                   *
21
 *                                                                         *
22
 ***************************************************************************/
23

24
#include <FCConfig.h>
25

26
#ifdef _PreComp_
27
# undef _PreComp_
28
#endif
29

30
#if defined(FC_OS_WIN32)
31
# include <windows.h>
32
#endif
33

34
#if defined(FC_OS_LINUX) || defined(FC_OS_BSD)
35
# include <unistd.h>
36
#endif
37

38
#ifdef FC_OS_MACOSX
39
# include <mach-o/dyld.h>
40
# include <string>
41
#endif
42

43
#if HAVE_CONFIG_H
44
# include <config.h>
45
#endif // HAVE_CONFIG_H
46

47
#include <cstdio>
48
#include <sstream>
49
#include <iostream>
50
#include <QByteArray>
51

52
// FreeCAD Base header
53
#include <Base/ConsoleObserver.h>
54
#include <Base/Exception.h>
55
#include <Base/PyObjectBase.h>
56
#include <Base/Sequencer.h>
57
#include <App/Application.h>
58

59
#if defined(FC_OS_WIN32)
60

61
/** DllMain is called when DLL is loaded
62
 */
63
BOOL APIENTRY DllMain(HANDLE hModule, DWORD  ul_reason_for_call, LPVOID /*lpReserved*/)
64
{
65
    switch (ul_reason_for_call) {
66
    case DLL_PROCESS_ATTACH: {
67
        // This name is preliminary, we pass it to Application::init() in initFreeCAD()
68
        // which does the rest.
69
        char  szFileName [MAX_PATH];
70
        GetModuleFileNameA((HMODULE)hModule, szFileName, MAX_PATH-1);
71
        App::Application::Config()["AppHomePath"] = szFileName;
72
    }
73
    break;
74
    default:
75
        break;
76
    }
77

78
    return true;
79
}
80
#elif defined(FC_OS_LINUX) || defined(FC_OS_BSD)
81
# ifndef GNU_SOURCE
82
#   define GNU_SOURCE
83
# endif
84
# include <dlfcn.h>
85
#elif defined(FC_OS_CYGWIN)
86
# include <windows.h>
87
#endif
88

89
PyMOD_INIT_FUNC(FreeCAD)
90
{
91
    // Init phase ===========================================================
92
    App::Application::Config()["ExeName"] = "FreeCAD";
93
    App::Application::Config()["ExeVendor"] = "FreeCAD";
94
    App::Application::Config()["AppDataSkipVendor"] = "true";
95

96
    QByteArray path;
97

98
#if defined(FC_OS_WIN32)
99
    path = App::Application::Config()["AppHomePath"].c_str();
100
#elif defined(FC_OS_CYGWIN)
101
    HMODULE hModule = GetModuleHandle("FreeCAD.dll");
102
    char szFileName [MAX_PATH];
103
    GetModuleFileNameA(hModule, szFileName, MAX_PATH-1);
104
    path = szFileName;
105
#elif defined(FC_OS_LINUX) || defined(FC_OS_BSD)
106
    putenv("LANG=C");
107
    putenv("LC_ALL=C");
108
    // get whole path of the library
109
    Dl_info info;
110
    int ret = dladdr((void*)PyInit_FreeCAD, &info);
111
    if ((ret == 0) || (!info.dli_fname)) {
112
        PyErr_SetString(PyExc_ImportError, "Cannot get path of the FreeCAD module!");
113
        return nullptr;
114
    }
115

116
    path = info.dli_fname;
117
    // this is a workaround to avoid a crash in libuuid.so
118
#elif defined(FC_OS_MACOSX)
119

120
    // The MacOS approach uses the Python sys.path list to find the path
121
    // to FreeCAD.so - this should be OS-agnostic, except these two
122
    // strings, and the call to access().
123
    const static char libName[] = "/FreeCAD.so";
124
    const static char upDir[] = "/../";
125

126
    PyObject *pySysPath = PySys_GetObject("path");
127
    if ( PyList_Check(pySysPath) ) {
128
        int i;
129
        // pySysPath should be a *PyList of strings - iterate through it
130
        // backwards since the FreeCAD path was likely appended just before
131
        // we were imported.
132
        for (i = PyList_Size(pySysPath) - 1; i >= 0 ; --i) {
133
            const char *basePath;
134
            PyObject *pyPath = PyList_GetItem(pySysPath, i);
135
            long sz = 0;
136

137
            if ( PyUnicode_Check(pyPath) ) {
138
                // Python 3 string
139
                basePath = PyUnicode_AsUTF8AndSize(pyPath, &sz);
140
            }
141
            else {
142
                continue;
143
            }
144

145
            if (sz + sizeof(libName) > PATH_MAX) {
146
                continue;
147
            }
148

149
            path = basePath;
150

151
            // append libName to the path
152
            if (access(path + libName, R_OK | X_OK) == 0) {
153

154
                // The FreeCAD "home" path is one level up from
155
                // libName, so replace libName with upDir.
156
                path += upDir;
157
                break;
158
            }
159
        } // end for (i = PyList_Size(pySysPath) - 1; i >= 0 ; --i) {
160
    } // end if ( PyList_Check(pySysPath) ) {
161

162
    if (path.isEmpty()) {
163
        PyErr_SetString(PyExc_ImportError, "Cannot get path of the FreeCAD module!");
164
        return nullptr;
165
    }
166

167
#else
168
# error "Implement: Retrieve the path of the module for your platform."
169
#endif
170
    int argc = 1;
171
    std::vector<char*> argv;
172
    argv.push_back(path.data());
173

174
    try {
175
        // Inits the Application
176
        App::Application::init(argc, argv.data());
177
    }
178
    catch (const Base::Exception& e) {
179
        std::string appName = App::Application::Config()["ExeName"];
180
        std::stringstream msg;
181
        msg << "While initializing " << appName << " the following exception occurred: '"
182
            << e.what() << "'\n\n";
183
        msg << "\nPlease contact the application's support team for more information.\n\n";
184
        printf("Initialization of %s failed:\n%s", appName.c_str(), msg.str().c_str());
185
    }
186

187
    Base::EmptySequencer* seq = new Base::EmptySequencer();
188
    (void)seq;
189
    static Base::RedirectStdOutput stdcout;
190
    static Base::RedirectStdLog    stdclog;
191
    static Base::RedirectStdError  stdcerr;
192
    std::cout.rdbuf(&stdcout);
193
    std::clog.rdbuf(&stdclog);
194
    std::cerr.rdbuf(&stdcerr);
195

196
    //PyObject* module = _PyImport_FindBuiltin("FreeCAD");
197
    PyObject* modules = PyImport_GetModuleDict();
198
    PyObject* module = PyDict_GetItemString(modules, "FreeCAD");
199
    if (!module) {
200
        PyErr_SetString(PyExc_ImportError, "Failed to load FreeCAD module!");
201
    }
202
    return module;
203
}
204

205

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.