Wrapping a Cplusplus class in Python/pl: Difference between revisions
(Created page with "==Opis klasy Plik XML==") |
(Created page with "Musisz utworzyć: * {{incode|[YourClass]Py.xml}} * {{incode|[YourClass]PyImp.cpp}}.") |
||
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: |
Revision as of 06:32, 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
The XML file [YourClass]Py.xml
provides information about the functions and attributes that the Python class implements, as well as the user documentation for those items that displays in the FreeCAD Python console.
For this example, we will look at the wrapper for the Axis C++ class. The XML description file begins with:
<?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>
Following this preamble, a list of methods and attributes is given. The format of a method is:
<Methode Name="move">
<Documentation>
<UserDocu>
move(Vector)
Move the axis base along the vector
</UserDocu>
</Documentation>
</Methode>
The format of an attribute is:
<Attribute Name="Direction" ReadOnly="false">
<Documentation>
<UserDocu>Direction vector of the Axis</UserDocu>
</Documentation>
<Parameter Name="Direction" Type="Object" />
</Attribute>
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:
Py::Object AxisPy::getDirection(void) const
and:
void AxisPy::setDirection(Py::Object arg)
Implementation Cplusplus File
The implementation C++ file [YourClass]PyImp.cpp
provides the "glue" that connects the C++ and Python structures together, effectively translating from one language to the other. The FreeCAD C++-to-Python system provides a number of C++ classes that map to their corresponding Python type. The most fundamental of these is the Py::Object
class -- rarely created directly, this class provides the base of the inheritance tree, and is used as the return type for any function that is returning Python data.
Include Files
Your C++ implementation file will include the following files:
#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"
Of course, you may include whatever other C++ headers your code requires to function as well.
Constructor
Your C++ implementation must contain the definition of the PyInit function: for example, for the Axis class wrapper, this is
int AxisPy::PyInit(PyObject* args, PyObject* /*kwd*/)
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 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:
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;
}
For a complete list of format specifiers see Python C API documentation. Note that several related functions are also defined which allow the use of keywords, etc. The complete set is:
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);
Links
- 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