Using the C++ interface

O2sclpy

C++ interface contents

C++ interface introduction

O₂sclpy includes several classes and functions which are wrappers around the original O₂scl classes and functions. The full documentation of these classes and functions is not reproduced here, but a link to the O₂scl documentation is provided. Note also that not all O₂scl functions are wrapped. In those O₂scl classes which are wrapped in O₂sclpy, not all of their methods or data members are accessible in O₂sclpy. If there is O₂scl which is missing and you would like me to include, let me know.

One o2sclpy.linker object should be created and then that object should be used to link the O₂scl libraries with the o2sclpy.linker.link_o2scl() function. Then, all O₂scl-based classes can be instantiated with the o2sclpy.linker object. In the __init__ methods of python wrappers of O₂scl classes, the pointer argument is optional and only needed if one is performing a shallow copy of an O₂scl-based class.

Generally, O₂sclpy should take care of the memory management for you. If they have ownership over their pointer, then their _owner data is True, and their __del__ method will call the C++ function necessary to free the memory associated with the underlying object. O₂sclpy contains wrappers to some std::shared_ptr objects, and these objects may not be destructed until the Python garbage collector deletes the last O₂sclpy class which owns a copy of the shared_ptr.

Throwing C++ exceptions across DLL boundaries is not supported in O₂scl, so O₂sclpy ensures that O₂scl uses an alternate error handler which calls exit() (i.e. from libc) when an error occurs. O₂sclpy does not support any interaction between Python and C++ exceptions.

Finally, some O₂scl classes output information to std::cout, and in a Jupyter notebook this normally goes to the Jupyter console. If you want this output to go to the Jupyter notebook instead, you will need to use the o2sclpy.cap_cout class.

Linking with O₂scl

The o2sclpy.linker class (see below) controls the dynamical loading of the O₂scl libraries. This class may require some additional information about your system in order to perform the dynamic loading properly.

The variable o2sclpy.linker.o2scl_cpp_lib specifies the C++ library to be loaded, in case it is not loaded automatically. The function o2sclpy.linker.get_library_settings() will set this to be the value of the environment variable O2SCL_CPP_LIB. You can also specify the C++ library on the command-line when using the O₂graph script using the o2scl-cpp-lib command. On a MacOS laptop, when using clang the C++ library is typically found automatically, but when using gcc I have to set this value to /usr/local/lib/gcc/11/libstdc++.dylib.

The variable o2sclpy.linker.o2scl_lib_dir specifies the directory where libo2scl.so is to be found, in case it cannot be found automatically. The function o2sclpy.linker.get_library_settings() will set this to be the value of the environment variable O2SCL_LIB_DIR. You can also specify the C++ library on the command-line when using the O₂graph script using the o2scl-lib-dir command.

Finally, the variable o2sclpy.linker.o2scl_addl_libs is a list of additional libraries which are required and not automatically included by the dynamic loading. The function o2sclpy.linker.get_library_settings() will set this to be the comma-separated list in the environment variable O2SCL_ADDL_LIBS. You can also specify the C++ library on the command-line when using the O₂graph script using the o2scl-addl-libs command. If O₂scl is installed with OpenMP support, the OpenMP libraries are often not automatically linked in, and so you may need to include something similar to /usr/local/lib/gcc/11/libgomp.1.dylib. Also, on my MacOS laptop, the readline library is not automatically included, so I typically use O2SCL_ADDL_LIBS=/usr/lib/libreadline.dylib,/usr/local/lib/gcc/11/libgomp.1.dylib.

Linking with O₂scl example

Use this link to view this example as a jupyter notebook on nbviewer.org.

# # O$_2$scl library linking example for O$_2$sclpy

# See the O$_2$sclpy documentation at
# https://awsteiner.org/code/o2sclpy for more information.

import sys
print(sys.path)

# +
import o2sclpy
import sys

plots=True
if 'pytest' in sys.modules:
    plots=False
# -

# This code dynamically links the O$_2$scl library. Environment
# variables can be used to specify the location of various libraries
# which need to be added. These values can also be set directly in the
# linker class (and then they override the environment variables). See
# http://awsteiner.org/code/o2sclpy/link_cpp.html#linking-with-o2scl
# for more detail. We set the verbose parameter to 1 to output more
# information about which libraries are being linked.

link=o2sclpy.linker()
link.verbose=1
link.link_o2scl()

# To test that the link worked, obtain the O$_2$scl version from the DLL:

print(link.o2scl_settings.o2scl_version())

def test_fun():
    assert link.o2scl_settings.o2scl_version()==b'0.929'
    return

Class linker

class o2sclpy.linker

The class which controls the dynamic linking of the O2scl libraries and also the setting of the matplotlib backend for o2graph. If O2scl is successfully linked, this class also provides access to the global O2scl library settings object.

backend = ''

Backend specification from command-line

get_library_settings(argv=[])

Get the library settings from environment variables or the command-line arguments

A function for linking the o2scl libraries.

o2scl = 0

Main o2scl library handle

o2scl_addl = []

Additional library handles

o2scl_addl_libs = []

Additional library list from command-line or environment variables

o2scl_cpp_lib = ''

C++ library from command-line or environment variables

o2scl_lib_dir = ''

O2scl library directory from command-line or environment variables

o2scl_settings = 0

The o2scl_settings object

systcpp = 0

System C++ library handle

verbose = 0

If greater than 0, output more information about the linker. The command-line option -debug-link sets this parameter to 1.