Calling C ++ Class Functions from Ruby / Python

In my particular case, I have a complex class (class of class classes) that I want to expose to a scripting language (aka Ruby). Rather, it is the fact that he passed this complex class, someone gave me the idea of ​​just opening a few functions for a scripting language such as Ruby, which seemed simpler. I saw Rice, but the only examples I saw use simple functions that just multiply something and not interact with the class.

For simplicity, I have a simple class with functions that I want to expose:

class Foo { private: //Integer Vector: std::vector<int> fooVector; public: //Functions to expose to Ruby: void pushBack(const int& newInt) {fooVector.push_back(newInt);} int& getInt(const int& element) {return fooVector.at(element);} }; 

ALSO:

I would rather just not have a link to the SWIG download page or an article explaining how to do this with rice written in 2010, I would like for the manual, which is most likely to work (I don't have much luck yet)

Aswell:

I use Linux (Ubuntu), but it is a cross-compatible program, so I should be able to compile on Windows and OS X

EDIT:

I understand that there are shared libraries (dlls and so on), but I don’t know if I can have a library that depends on the .hpp file containing the class (s).

+6
source share
2 answers

You can use cython or Boost.Python to call native code from python. Since you are using C ++, I would recommend exploring Boost.Python , which offers a very natural way of wrapping C ++ classes for python.

As an example (next to what you provide), consider the following class definitions

 class Bar { private: int value; public: Bar() : value(42){ } //Functions to expose to Python: int getValue() const { return value; } void setValue(int newValue) { value = newValue; } }; class Foo { private: //Integer Vector: std::vector<int> fooVector; Bar bar; public: //Functions to expose to Python: void pushBack(const int& newInt) { fooVector.push_back(newInt); } int getInt(const int& element) { return fooVector.at(element); } Bar& getBar() { return bar; } }; double compute() { return 18.3; } 

This can be wrapped in python using Boost.Python

 #include <boost/python.hpp> BOOST_PYTHON_MODULE(MyLibrary) { using namespace boost::python; class_<Foo>("Foo", init<>()) .def("pushBack", &Foo::pushBack, (arg("newInt"))) .def("getInt", &Foo::getInt, (arg("element"))) .def("getBar", &Foo::getBar, return_value_policy<reference_existing_object>()) ; class_<Bar>("Bar", init<>()) .def("getValue", &Bar::getValue) .def("setValue", &Bar::setValue, (arg("newValue"))) ; def("compute", compute); } 

This code can be compiled into the static library MyLibrary.pyd and used like this

 import MyLibrary foo = MyLibrary.Foo() foo.pushBack(10); foo.pushBack(20); foo.pushBack(30); print(foo.getInt(0)) # 10 print(foo.getInt(1)) # 20 print(foo.getInt(2)) # 30 bar = foo.getBar() print(bar.getValue()) # 42 bar.setValue(17) print(foo.getBar().getValue()) #17 print(MyLibrary.compute()) # 18.3 
+2
source

What about Boost.Python ?

Why don't you want to use SWIG?

0
source

Source: https://habr.com/ru/post/988397/


All Articles