I want to know if there is any way to expose a C++ class to Python but without building an intermediate shared library.
Here is my desirable scenario. For example I have following C++ class:
class toto
{
public:
toto(int iValue1_, int iValue2_): iValue1(iValue1_), iValue2(iValue2_) {}
int Addition(void) const {if (!this) return 0; return iValue1 + iValue2;}
private:
int iValue1;
int iValue2;
};
I would like to convert somehow this class (or its intance) to a PyObject* in order to send it as paremter (args) to for example PyObject_CallObject:
PyObject* PyObject_CallObject(PyObject* wrapperFunction, PyObject* args)
In the other hand in my python side, I'll have a wrapperFunction which gets the pointer on my C++ class (or its instance) as parameter and it calls its methods or uses its properties:
def wrapper_function(cPlusPlusClass):
instance = cPlusPlusClass(4, 5)
result = instance.Addition()
As you can see, I don't really need/want to have a separate shared library or build a module by boost python. All that I need is to find a way to convert a C++ code to PyObject and send it to python. I cannot find a way to do that by C python libraries, boost or SWIG.
I found my answer. Actually what I was searching was pretty similar to this answer (thanks moooeeeep for his comment):
Exposing a C++ class instance to a python embedded interpreter
Following C++ class (Attention! default constructor is mandatory):
class TwoValues
{
public:
TwoValues(void): iValue1(0), iValue2(0) {}
TwoValues(int iValue1, int iValue2): iValue1(iValue1_), iValue2(iValue2_) {}
int Addition(void) const {if (!this) return 0; return iValue1 + iValue2;}
public:
int iValue1;
int iValue2;
};
could be exposed by boost by following macro:
BOOST_PYTHON_MODULE(ModuleTestBoost)
{
class_<TwoValues>("TwoValues")
.def("Addition", &TWOVALUES::Addition)
.add_property("Value1", &TWOVALUES::iValue1)
.add_property("Value2", &TWOVALUES::iValue2);
};
In the other hand I have a python function defined in python_script.py
which takes an instance of this class and do something. For example:
def wrapper_function(instance):
result = instance.Addition()
myfile = open(r"C:\...\testboostexample.txt", "w")
output = 'First variable is {0}, second variable is {1} and finally the addition is {2}'.format(instance.Value1, instance.Value2, result)
myfile .write(output)
myfile .close()
Then in C++ side, I can call this function by sending at the same time the instance of my class, like this:
Py_Initialize();
try
{
TwoValues instance(5, 10);
initModuleTestBoost();
object python_script = import("python_script");
object wrapper_function = python_script.attr("wrapper_function");
wrapper_function(&instance);
}
catch (error_already_set)
{
PyErr_Print();
}
Py_Finalize();
Advantages: