1

I am facing a problem, yesterday I made a post asking how to import a C++ funtion in Python: Post. In this post they suggested me to use Boost Python. So I started to learn it. However all the tutorials are really complicated for me. I know Python language but I am learing C++ so I found it difficult to understand. The other point is that in all the posts that I have found here they talk about 1D vectors in C++, but my function takes 2D vectors.

Indeed all the posts usually employ a C++ class instead of a function. And I don't know anything about classes in C++. But I found it useless in my case since I only whant to evaluate a function and return the result (double) to python. So the first question is. Is It completaley necessary to employ classes instead of functions for Boost python?

As you can see in the other post my function have the following structure:

double many_body_pot(
std::vector< std::vector<double> > &par,
std::vector< std::vector<double> > &geometry,
double x, double y, double z)
{
   // ...
}

So it takes 2 2D vectors and 3 doubles as parameters. So what I have learned until now is I have to use #include <boost/python.hpp> in my C++ script and I have to include something like this:

BOOST_PYTHON_MODULE(many_body_pot) {
    using namespace boost::python;
    def("many_body_pot", many_body_pot);
}

I Python have to send rather 2D ndarrays or 2D lists to the function to be converted to 2D vectors. And if I use 2D ndarrays I will have to use numpy Boost. In my case I don't mind to use one or the other. But I don't understand how to do the conversion to 2D vectors. Could you please give me an easy-to-understand solution for this? It would be really appreciated.

Thank you

Community
  • 1
  • 1
Kilian A.G.
  • 123
  • 1
  • 6

1 Answers1

0

C++ has a complicated learning curve for people who only know scripting. C++ has much more freedom than you could ever imagine. This freedom can be a curse for new learners. So unless you dedicate some time to understand how C++ works, you're not only gonna do the job wrong, but you may also do it inefficiently.

I know this might not directly be the answer to your question, but if you want to avoid using classes, then consider using Python's ctypes. You can create a shared library, and then import it in Python.

I, personally, am a big opponent of adding unnecessary libraries unless you have to. And I think the freedom provided by ctypes and the backward/forward compatibility with almost all Python versions and the possibility to decouple your C++ work from Python is priceless. So, consider using ctypes, and then all you have to learn is how to create functions and how to compile them to shared libraries. And since you're a Python expert, you won't have a problem importing that to Python and utilizing it.

The Quantum Physicist
  • 24,987
  • 19
  • 103
  • 189
  • I have considered using ctypes. However I have read that It only works with C not C++. I am right? – Kilian A.G. Oct 25 '16 at 11:29
  • @KilianArteagaGutierrez No, this is not right at all. The interface to Python is C (which is why it's only functions); meaning that your function calls are C functions, but all the internal mechanics can be C or C++ or even assembly. Anything that works in your C++ program is fine there. I do this all the time actually, where I include complicated C++ classes that have templates and everything (that have nothing to do with C). – The Quantum Physicist Oct 25 '16 at 11:38
  • Ok, I have followed your advice, I was able to pass 2D ndarrays to a function in C with Python-numpy API. Now I am trying to build the real module which have 3 functions. Each function is a method in the API, so know I am facing a problem. Supose that I want one of the function without returning anything, but I want it to define a variable/array whatever that can be accesed by the other methods. So the question is, if I define it inside of one method will it be accesible or I have to do something special? – Kilian A.G. Oct 27 '16 at 13:32
  • @KilianArteagaGutierrez The answer is very simple, but you have to do it right. You simply make a pointer to your variable, and give it back to Python, and then pass it further to the other function. If you have multiple variables, put them all in a `struct` object. – The Quantum Physicist Oct 27 '16 at 15:44