The following sources include a class, a function and a template.
%%python
code='''
#include <iostream>
#include <typeinfo>
/// A trivial class
class A {
public:
A();
~A();
};
/// A trivial function
int CountCharacters(const std::string s);
/// A trivial template
template<class T>
class B {
public:
B()
{
std::cout << "The typeid name of the template argument is " << typeid(T).name() << std::endl;
}
};
'''
with open('myLibrary.h','w') as f_out:
f_out.write(code)
%%python
code='''
#include "myLibrary.h"
A::A()
{
std::cout << "This is the constructor of A" << std::endl;
}
A::~A()
{
std::cout << "This is the destructor of A" << std::endl;
}
int CountCharacters(const std::string s)
{
return s.size();
}
'''
with open('myLibrary.cc','w') as f_out:
f_out.write(code)
It's trivial to create a shared object starting from the sources above:
%%bash
g++ -o libmyLibrary.so -shared -fPIC myLibrary.cc
%%bash
ls *so
libmyLibrary.so
So far, so good. Now we'll see how easy it is to use this library from within Python thanks to ROOT.
In order to interact with the C++ entities contained in the library, we need to carry out to tasks:
In code:
import ROOT
ROOT.gInterpreter.ProcessLine('#include "myLibrary.h"')
ROOT.gSystem.Load("./libmyLibrary.so")
Welcome to JupyROOT 6.07/07
0
That's it! We can now start exploring the content of the library. If you are wondering what a return code equal to 0 means, ROOT is telling us that the loading of the library happened without problems!
a = ROOT.A()
This is the constructor of A
del a
This is the destructor of A
b_doublePtr = ROOT.B("double*")()
The typeid name of the template argument is Pd
Notice how the "impedence mismatch" generated by the concept of templates is ironed out in this case. The template parameter is specified as string in parentheses.
ROOT.CountCharacters("This interactivity without bindings is really impressive.")
57
Interactive usage of C++ libraries is possible also in C++ mode. In this case, no wrapper is interposed between the statement written by the user and the call - ABI compatibility is leveraged. For example:
%%cpp
A a;
This is the constructor of A