FreeCAD

Форк
0
/
MainPy.cpp 
201 строка · 6.9 Кб
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
        } break;
73
        default:
74
            break;
75
    }
76

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

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

95
    QByteArray path;
96

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

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

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

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

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

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

148
            path = basePath;
149

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

153
                // The FreeCAD "home" path is one level up from
154
                // libName, so replace libName with upDir.
155
                path += upDir;
156
                break;
157
            }
158
        }
159
    }
160

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

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

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

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

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

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

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

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

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