diff options
Diffstat (limited to 'examples/samplebinding/README.md')
-rw-r--r-- | examples/samplebinding/README.md | 245 |
1 files changed, 0 insertions, 245 deletions
diff --git a/examples/samplebinding/README.md b/examples/samplebinding/README.md deleted file mode 100644 index 26ff2b383..000000000 --- a/examples/samplebinding/README.md +++ /dev/null @@ -1,245 +0,0 @@ -# Sample bindings example - -This example showcases how to generate Python bindings for a -non-Qt C++ library. - -The example defines a CMake project that builds two libraries: -* `libuniverse` - a sample library with two C++ classes. -* `Universe` - the generated Python extension module that contains - bindings to the library above. - -The project file is structured in such a way that a user can copy-paste -in into their own project, and be able to build it with a minimal amount -of modifications. - -## Description - -The libuniverse library declares two classes: `Icecream` and `Truck`. - -`Icecream` objects have a flavor, and an accessor for returning the -flavor. - -`Truck` instances store a vector of `Icecream` objects, and have various -methods for adding new flavors, printing available flavors, delivering -icecream, etc. - -From a C++ perspective, `Icecream` instances are treated as -**object types** (pointer semantics) because the class declares virtual -methods. - -In contrast `Truck` does not define virtual methods and is treated as -a **value type** (copy semantics). - -Because `Truck` is a value type and it stores a vector of `Icecream` -pointers, the rule of three has to be taken into account (implement the -copy constructor, assignment operator, destructor). - -And due to `Icecream` objects being copyable, the type has to define an -implementation of the *clone()* method, to avoid type slicing issues. - -Both of these types and their methods will be exposed to Python by -generating CPython code. The code is generated by **shiboken** and -placed in separate ".cpp" files named after each C++ type. The code is -then compiled and linked into a shared library. The shared library is a -CPython extension module, which is loaded by the Python interpreter. - -Beacuse the C++ language has different semantics to Python, shiboken -needs help in figuring out how to generate the bindings code. This is -done by specifying a special XML file called a typesystem file. - -In the typesystem file you specify things like: - * which C++ primitive types should have bindings (int, bool, float) - * which C++ classes should have bindings (Icecream) and what kind of - semantics (value / object) - * Ownership rules (who deletes the C++ objects, C++ or Python) - * Code injection (for various special cases that shiboken doesn't know - about) - * Package name (name of package as imported from Python) - -In this example we declare `bool` and `std::string` as primitive types, -`Icecream` as an object type, `Truck` as a value type, -and the `clone()` and `addIcecreamFlavor(Icecream*)` need additional -info about who owns the parameter objects when passing them across -language boundaries (in this case C++ will delete the objects). - -The `Truck` has getters and setters for the string `arrivalMessage`. -In the type system file, we declare this to be a property in Python: - -``` -<property type="std::string" name="arrivalMessage" get="getArrivalMessage" set="setArrivalMessage"/> -``` - -It can then be used in a more pythonic way: - -``` -special_truck.arrivalMessage = "A new SPECIAL icecream truck has arrived!\n" -``` - -After shiboken generates the C++ code and CMake makes an extension -module from the code, the types can be accessed in Python simply by -importing them using the original C++ names. - -``` -from Universe import Icecream, Truck -``` - -Constructing C++ wrapped objects is the same as in Python -``` -icecream = Icecream("vanilla") -truck = Truck() -``` - - -And actual C++ constructors are mapped to the Python `__init__` method. -``` -class VanillaChocolateIcecream(Icecream): - def __init__(self, flavor=""): - super().__init__(flavor) -``` - - -C++ methods can be accessed as regular Python methods using the C++ -names -``` -truck.addIcecreamFlavor(icecream) -``` - - -Inheritance works as with regular Python classes, and virtual C++ -methods can be overridden simply by definining a method with the same -name as in the C++ class. -``` -class VanillaChocolateIcecream(Icecream): - # ... - def getFlavor(self): - return "vanilla sprinked with chocolate" - -``` - - -The `main.py` script demonstrates usages of these types. - -The CMake project file contains many comments explaining all the build -rules for those interested in the build process. - -## Building the project - -This example can only be built using **CMake**. -The following requirements need to be met: - -* A PySide package is installed into the current active Python - environment (system or virtualenv) -* A new enough version of CMake (**3.1+**). -* ninja - -For Windows you will also need: -* a Visual Studio environment to be active in your terminal -* Correct visual studio architecture chosen (32 vs 64 bit) -* Make sure that your Python intepreter and bindings project build - configuration is the same (all Release, which is more likely, - or all Debug). - -The build uses the `pyside_config.py` file to configure the project -using the current PySide/Shiboken installation. - -### Using CMake - -You can build and run this example by executing the following commands -(slightly adapted to your file system layout) in a terminal: - -macOS/Linux: -```bash -cd ~/pyside-setup/examples/samplebinding -``` - -On Windows: -```bash -cd C:\pyside-setup\examples\samplebinding -``` - -```bash -mkdir build -cd build -mkdir build -cd build -cmake -H.. -B. -G Ninja -DCMAKE_BUILD_TYPE=Release -ninja -ninja install -cd .. -``` - -The final example can then be run by: -```bash -python main.py -``` - -#### Windows troubleshooting - -It is possible that **CMake** can pick up the wrong compiler -for a different architecture, but it can be addressed explicitly -by setting the **CC** environment variable: - -```bash -set CC=cl -``` - -or by using the -G option: - -```bash -cmake -H.. -B. -G "Visual Studio 14 Win64" -``` - -If the `-G "Visual Studio 14 Win64"` option is used, a `sln` file -will be generated, and can be used with `MSBuild` -instead of `nmake/jom`. -The easiest way to both build and install in this case, is to use -the cmake executable: - -```bash -cmake --build . --target install --config Release -``` - -Note that using the "NMake Makefiles JOM" generator is preferred to -the MSBuild one, because the MSBuild one generates configs for both -Debug and Release, and this might lead to building errors if you -accidentally build the wrong config at least once. - -## Virtualenv Support - -If the python application is started from a terminal with an activated -python virtual environment, that environment's packages will be used for -the python module import process. -In this case, make sure that the bindings were built while the -`virtualenv` was active, so that the build system picks up the correct -python shared library and PySide6 / shiboken package. - -## Linux Shared Libraries Notes - -For this example's purpose, we link against the absolute path of the -dependent shared library `libshiboken` because the -installation of the library is done via a wheel, and there is -no clean solution to include symbolic links in a wheel package -(so that passing -lshiboken to the linker would work). - -## Windows Notes - -The build config of the bindings (Debug or Release) should match -the PySide build config, otherwise the application will not properly -work. - -In practice this means the only supported configurations are: - -1. release config build of the bindings + - PySide `setup.py` without `--debug` flag + `python.exe` for the - PySide build process + `python36.dll` for the linked in shared - library. -2. debug config build of the application + - PySide `setup.py` **with** `--debug` flag + `python_d.exe` for the - PySide build process + `python36_d.dll` for the linked in shared - library. - -This is necessary because all the shared libraries in question have to -link to the same C++ runtime library (`msvcrt.dll` or `msvcrtd.dll`). -To make the example as self-contained as possible, the shared libraries -in use (`pyside6.dll`, `shiboken6.dll`) are hard-linked into the build -folder of the application. |