Wrapping a Cplusplus class in Python/pl: Difference between revisions
(Created page with "Edytuj odpowiedni plik {{FileName|CMakeLists.txt}}, aby dodać odniesienia do tych dwóch plików. Z pliku XML system kompilacji utworzy następnie: * {{incode|[YourClass]Py.cpp}} * {{incode|[YourClass]Py.h}}.") |
(Created page with "Pełna lista specyfikatorów formatu znajduje się na stronie [https://docs.python.org/3/c-api/arg.html dokumentacja Python C API]. Należy pamiętać, że zdefiniowano również kilka powiązanych funkcji, które pozwalają na użycie słów kluczowych itp. Kompletny zestaw to:") |
||
(18 intermediate revisions by the same user not shown) | |||
Line 9: | Line 9: | ||
FreeCAD używa niestandardowego systemu opartego na XML do tworzenia opakowania Pythona dla klasy C++. Aby opakować klasę C++ do użytku w środowisku Python, należy ręcznie utworzyć dwa pliki, a dwa pliki są automatycznie generowane przez system kompilacji CMake ''(oprócz plików nagłówkowych i implementacyjnych C++ dla klasy)''. |
FreeCAD używa niestandardowego systemu opartego na XML do tworzenia opakowania Pythona dla klasy C++. Aby opakować klasę C++ do użytku w środowisku Python, należy ręcznie utworzyć dwa pliki, a dwa pliki są automatycznie generowane przez system kompilacji CMake ''(oprócz plików nagłówkowych i implementacyjnych C++ dla klasy)''. |
||
Musisz utworzyć: |
|||
You must create: |
|||
* {{incode|[YourClass]Py.xml}} |
* {{incode|[YourClass]Py.xml}} |
||
* {{incode|[YourClass]PyImp.cpp}} |
* {{incode|[YourClass]PyImp.cpp}}. |
||
Edytuj odpowiedni plik {{FileName|CMakeLists.txt}}, aby dodać odniesienia do tych dwóch plików. Z pliku XML system kompilacji utworzy następnie: |
Edytuj odpowiedni plik {{FileName|CMakeLists.txt}}, aby dodać odniesienia do tych dwóch plików. Z pliku XML system kompilacji utworzy następnie: |
||
Line 17: | Line 17: | ||
* {{incode|[YourClass]Py.h}}. |
* {{incode|[YourClass]Py.h}}. |
||
<span id="Class_Description_XML_File"></span> |
|||
== Class Description XML File == |
|||
==Opis klasy Plik XML== |
|||
Plik XML {{incode|[YourClass]Py.xml}} zawiera informacje o funkcjach i atrybutach, które implementuje klasa Python, a także dokumentację użytkownika dla tych elementów, która wyświetla się w [[Python_console/pl|konsoli FreeCAD]]. |
|||
W tym przykładzie przyjrzymy się wrapperowi dla klasy Axis C++. Plik opisu XML zaczyna się od: |
|||
For this example, we will look at the wrapper for the Axis C++ class. The XML description file begins with: |
|||
{{Code|lang=xml|code= |
{{Code|lang=xml|code= |
||
Line 46: | Line 47: | ||
}} |
}} |
||
Po tej preambule podana jest lista metod i atrybutów. Format metody jest następujący: |
|||
Following this preamble, a list of methods and attributes is given. The format of a method is: |
|||
{{Code|lang=xml|code= |
{{Code|lang=xml|code= |
||
Line 59: | Line 60: | ||
}} |
}} |
||
Format atrybutu jest następujący: |
|||
The format of an attribute is: |
|||
{{Code|lang=xml|code= |
{{Code|lang=xml|code= |
||
Line 70: | Line 71: | ||
}} |
}} |
||
W przypadku atrybutu, jeśli "ReadOnly" ma wartość false, należy podać zarówno funkcję pobierającą, jak i ustawiającą. Jeśli natomiast ma wartość true, dozwolona jest tylko funkcja getter. W tym przypadku będziemy musieli dostarczyć dwie funkcje w pliku implementacji C++: |
|||
For an attribute, if "ReadOnly" is false, you will provide both a getter and a setter function. If it is true, only a getter is allowed. In this case we will be required to provide two functions in the implementation C++ file: |
|||
{{Code|lang=cpp|code= |
{{Code|lang=cpp|code= |
||
Line 76: | Line 77: | ||
}} |
}} |
||
oraz: |
|||
and: |
|||
{{Code|lang=cpp|code= |
{{Code|lang=cpp|code= |
||
Line 82: | Line 83: | ||
}} |
}} |
||
<span id="Implementation_Cplusplus_File"></span> |
|||
== Implementation Cplusplus File == |
|||
==Implementacja pliku Cplusplus== |
|||
Plik implementacji C++ {{incode|[YourClass]PyImp.cpp}} zapewnia "klej", który łączy ze sobą struktury C++ i Python, skutecznie tłumacząc z jednego języka na drugi. System FreeCAD C++-to-Python zapewnia szereg klas C++, które mapują się na odpowiadające im typy Pythona. Najbardziej podstawową z nich jest klasa {{incode|Py::Object}} - rzadko tworzona bezpośrednio, klasa ta stanowi podstawę drzewa dziedziczenia i jest używana jako typ zwracany dla każdej funkcji zwracającej dane z języka Python. |
|||
<span id="Include_Files"></span> |
|||
=== Include Files === |
|||
===Dołączanie plików=== |
|||
Twój plik implementacyjny C++ będzie zawierać następujące pliki: |
|||
Your C++ implementation file will include the following files: |
|||
{{Code|lang=cpp|code= |
{{Code|lang=cpp|code= |
||
Line 100: | Line 103: | ||
}} |
}} |
||
Oczywiście można dołączyć wszelkie inne nagłówki C++, których kod wymaga do działania. |
|||
Of course, you may include whatever other C++ headers your code requires to function as well. |
|||
= |
<span id="Constructor"></span> |
||
===Konstruktor=== |
|||
Twoja implementacja C++ musi zawierać definicję funkcji PyInit: na przykład dla wrappera klasy Axis jest to: |
|||
Your C++ implementation must contain the definition of the PyInit function: for example, for the Axis class wrapper, this is |
|||
{{Code|lang=cpp|code= |
{{Code|lang=cpp|code= |
||
Line 110: | Line 114: | ||
}} |
}} |
||
W ramach tej funkcji najprawdopodobniej będziesz musiał przeanalizować argumenty przychodzące do konstruktora: najważniejszą funkcją do tego celu jest dostarczona przez środowisko Python {{incode|PyArg_ParseTuple}}. Przyjmuje ona przekazaną listę argumentów, deskryptor oczekiwanych argumentów, które powinna przeanalizować, oraz informacje o typie i lokalizacje przechowywania przeanalizowanych wyników. Na przykład: |
|||
Within this function you will most likely need to parse incoming arguments to the constructor: the most important function for this purpose is the Python-provided {{incode|PyArg_ParseTuple}}. It takes in the passed argument list, a descriptor for the expected arguments that it should parse, and type information and storage locations for the parsed results. For example: |
|||
{{Code|lang=cpp|code= |
{{Code|lang=cpp|code= |
||
Line 123: | Line 127: | ||
}} |
}} |
||
Pełna lista specyfikatorów formatu znajduje się na stronie [https://docs.python.org/3/c-api/arg.html dokumentacja Python C API]. Należy pamiętać, że zdefiniowano również kilka powiązanych funkcji, które pozwalają na użycie słów kluczowych itp. Kompletny zestaw to: |
|||
{{Code|lang=cpp|code= |
{{Code|lang=cpp|code= |
||
Line 133: | Line 137: | ||
}} |
}} |
||
= |
<span id="Links"></span> |
||
==Odnośniki internetowe== |
|||
* [[Exposing_Cplusplus_to_Python| |
* [[Exposing_Cplusplus_to_Python|Udostępnianie Cplusplus w środowisku Python]] |
||
* [https://github.com/FreeCAD/FreeCAD/commit/20b86e55b8dd1873f4c19e036d047528c9ff7f4e Commit 20b86e5, |
* [https://github.com/FreeCAD/FreeCAD/commit/20b86e55b8dd1873f4c19e036d047528c9ff7f4e Commit 20b86e5, eksponujący precyzyjne metody OCC w środowisku Python]. |
||
Latest revision as of 08:49, 6 November 2023
Kontekst
FreeCAD używa niestandardowego systemu opartego na XML do tworzenia opakowania Pythona dla klasy C++. Aby opakować klasę C++ do użytku w środowisku Python, należy ręcznie utworzyć dwa pliki, a dwa pliki są automatycznie generowane przez system kompilacji CMake (oprócz plików nagłówkowych i implementacyjnych C++ dla klasy).
Musisz utworzyć:
[YourClass]Py.xml
[YourClass]PyImp.cpp
.
Edytuj odpowiedni plik CMakeLists.txt, aby dodać odniesienia do tych dwóch plików. Z pliku XML system kompilacji utworzy następnie:
[YourClass]Py.cpp
[YourClass]Py.h
.
Opis klasy Plik XML
Plik XML [YourClass]Py.xml
zawiera informacje o funkcjach i atrybutach, które implementuje klasa Python, a także dokumentację użytkownika dla tych elementów, która wyświetla się w konsoli FreeCAD.
W tym przykładzie przyjrzymy się wrapperowi dla klasy Axis C++. Plik opisu XML zaczyna się od:
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="PyObjectBase"
Name="AxisPy"
Twin="Axis"
TwinPointer="Axis"
Include="Base/Axis.h"
FatherInclude="Base/PyObjectBase.h"
Namespace="Base"
Constructor="true"
Delete="true"
FatherNamespace="Base">
<Documentation>
<Author Licence="LGPL" Name="Juergen Riegel" EMail="FreeCAD@juergen-riegel.net" />
<UserDocu>User documentation here
</UserDocu>
<DeveloperDocu>Developer documentation here</DeveloperDocu>
</Documentation>
Po tej preambule podana jest lista metod i atrybutów. Format metody jest następujący:
<Methode Name="move">
<Documentation>
<UserDocu>
move(Vector)
Move the axis base along the vector
</UserDocu>
</Documentation>
</Methode>
Format atrybutu jest następujący:
<Attribute Name="Direction" ReadOnly="false">
<Documentation>
<UserDocu>Direction vector of the Axis</UserDocu>
</Documentation>
<Parameter Name="Direction" Type="Object" />
</Attribute>
W przypadku atrybutu, jeśli "ReadOnly" ma wartość false, należy podać zarówno funkcję pobierającą, jak i ustawiającą. Jeśli natomiast ma wartość true, dozwolona jest tylko funkcja getter. W tym przypadku będziemy musieli dostarczyć dwie funkcje w pliku implementacji C++:
Py::Object AxisPy::getDirection(void) const
oraz:
void AxisPy::setDirection(Py::Object arg)
Implementacja pliku Cplusplus
Plik implementacji C++ [YourClass]PyImp.cpp
zapewnia "klej", który łączy ze sobą struktury C++ i Python, skutecznie tłumacząc z jednego języka na drugi. System FreeCAD C++-to-Python zapewnia szereg klas C++, które mapują się na odpowiadające im typy Pythona. Najbardziej podstawową z nich jest klasa Py::Object
- rzadko tworzona bezpośrednio, klasa ta stanowi podstawę drzewa dziedziczenia i jest używana jako typ zwracany dla każdej funkcji zwracającej dane z języka Python.
Dołączanie plików
Twój plik implementacyjny C++ będzie zawierać następujące pliki:
#include "PreCompiled.h"
#include "[YourClass].h"
// Inclusion of the generated files (generated out of [YourClass]Py.xml)
#include "[YourClass]Py.h"
#include "[YourClass]Py.cpp"
Oczywiście można dołączyć wszelkie inne nagłówki C++, których kod wymaga do działania.
Konstruktor
Twoja implementacja C++ musi zawierać definicję funkcji PyInit: na przykład dla wrappera klasy Axis jest to:
int AxisPy::PyInit(PyObject* args, PyObject* /*kwd*/)
W ramach tej funkcji najprawdopodobniej będziesz musiał przeanalizować argumenty przychodzące do konstruktora: najważniejszą funkcją do tego celu jest dostarczona przez środowisko Python PyArg_ParseTuple
. Przyjmuje ona przekazaną listę argumentów, deskryptor oczekiwanych argumentów, które powinna przeanalizować, oraz informacje o typie i lokalizacje przechowywania przeanalizowanych wyników. Na przykład:
PyObject* d;
if (PyArg_ParseTuple(args, "O!O", &(Base::VectorPy::Type), &o,
&(Base::VectorPy::Type), &d)) {
// NOTE: The first parameter defines the base (origin) and the second the direction.
*getAxisPtr() = Base::Axis(static_cast<Base::VectorPy*>(o)->value(),
static_cast<Base::VectorPy*>(d)->value());
return 0;
}
Pełna lista specyfikatorów formatu znajduje się na stronie dokumentacja Python C API. Należy pamiętać, że zdefiniowano również kilka powiązanych funkcji, które pozwalają na użycie słów kluczowych itp. Kompletny zestaw to:
PyAPI_FUNC(int) PyArg_Parse (PyObject *, const char *, ...);
PyAPI_FUNC(int) PyArg_ParseTuple (PyObject *, const char *, ...);
PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords (PyObject *, PyObject *, const char *, char **, ...);
PyAPI_FUNC(int) PyArg_VaParse (PyObject *, const char *, va_list);
PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords (PyObject *, PyObject *, const char *, char **, va_list);
Odnośniki internetowe
- Udostępnianie Cplusplus w środowisku Python
- Commit 20b86e5, eksponujący precyzyjne metody OCC w środowisku Python.
- Tworzenie skryptów FreeCAD: Python, Wprowadzenie do środowiska Python, Poradnik: Tworzenie skryptów Python, Podstawy tworzenia skryptów FreeCAD
- Moduły: Moduły wbudowane, Jednostki miar, Ilość
- Środowiska pracy: Tworzenie Środowiska pracy, Polecenia Gui, Polecenia, Instalacja większej liczby Środowisk pracy
- Siatki i elementy: Skrytpy w Środowisku Siatek, v, Konwerska Mesh na Part, PythonOCC
- Obiekty parametryczne: Obiekty tworzone skryptami, Obsługa obrazu (Ikonka niestandardowa w widoku drzewa)
- Scenegraph: Coin (Inventor) scenegraph, Pivy
- Interfejs graficzny: Stworzenie interfejsu, Kompletne stworzenie interfejsu w środowisku Python (1, 2, 3, 4, 5), PySide, PySide examples początkujący, średniozaawansowany, zaawansowany
- Makrodefinicje: Makrodefinicje, Instalacja makrodefinicji
- Osadzanie programu: Osadzanie programu FreeCAD, Osadzanie GUI FreeCAD
- Pozostałe: Wyrażenia, Wycinki kodu, Funkcja kreślenia linii, Biblioteka matematyczna FreeCAD dla wektorów (deprecated)
- Węzły użytkowników: Centrum użytkownika, Centrum Power użytkowników, Centrum programisty