The following sources include a class, a function and a template.
In [1]:
%%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)
In [2]:
%%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)
In [3]:
%%bash
g++ -o libmyLibrary.so -shared -fPIC myLibrary.cc
In [4]:
%%bash
ls *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:
In [5]:
import ROOT
ROOT.gInterpreter.ProcessLine('#include "myLibrary.h"')
ROOT.gSystem.Load("./libmyLibrary.so")
Out[5]:
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!
In [6]:
a = ROOT.A()
In [7]:
del a
In [8]:
b_doublePtr = ROOT.B("double*")()
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.
In [9]:
ROOT.CountCharacters("This interactivity without bindings is really impressive.")
Out[9]:
In [10]:
%%cpp
A a;