Python is the best glue language in the world (PHP is the best language in the world, of course), and the simplicity of Python and the efficiency of C++ can solve 99% of the problems

In general, Python and C++ interactions fall into two categories:

  1. Extending Python with C++ : when a performance bottleneck occurs in a Python project, remove the bottleneck and wrap it in C++ into a module that Python can call (the so library);
  2. Embed C++ in Python: when a C++ project has features that are expected to change frequently for greater flexibility, implement those features in Python and call them in C++. This article will briefly introduce one of the practices in the first part.

Boost.Python

Boost is a treasure trove that provides the functionality we need. Also, Boost.Python is used by default in many of Boost’s libraries, so it’s been well tested.

The installation

Most of Boost’s functionality is provided as a header file, requiring no installation; However, there are a few features that need to be compiled manually. Unfortunately, Boost.Python is one of them.

See Part 5 of Getting Started on Unix to find out how Boost.Python will be installed. Once the installation is complete, you can see the relevant so files in the relevant directory (mine is /usr/local/lib).

Hello World

Implement a module in C++ that, when called in Python, returns a specific string.

#include <boost/python.hpp>

char const* greet()
{
	return "hello, boost";
}

BOOST_PYTHON_MODULE(hello_boostpy)
{
	using namespace boost::python;
	def("greet", greet);
}
Copy the code

Too simple, the code basically says it all ~

Compile it into a dynamically linked library form:

G++ -i /usr/include/python2.7/-fpic-shared -o hello_boostpy.so hello_boostpy.cc -lboost_pythonCopy the code

You can use LDD to see if hello_boostpy.so can find libboost_python. If not, add its path manually to the environment variable LD_LIBRARY_PATH, or use ldconfig.

Now you can use the hello_boostpy library in Python:

# -*- coding: utf-8 -*-
import sys
sys.path.append('.')


def test():
    import hello_boostpy
    return hello_boostpy.greet()


if __name__ == "__main__":
    print test()
Copy the code

Expose Class

Next, we add a class to our C++ implementation module and try passing Python’s list object in the C++ direction.

C + + class:

#include <boost/python.hpp>
#include <vector>
#include <string>
#include <sstream>
using namespace boost::python;

struct Person
{
	void set_name(std::string name) { this->name = name; }
	std::string print_info();
	void set_items(list& prices, list& discounts);
	
	
	std::string name;
	std::vector<double> item_prices;
	std::vector<double> item_discounts;
};
Copy the code

Boost :: Python :: List (dict, tuple, etc.) is implemented in Python to Boost :: Python ::list. In set_items, we’ll do a conversion to the data type using boost:: Python ::extract.

void Person::set_items(list& prices, list& discounts) { for(int i = 0; i < len(prices); ++i) { double price = extract<double>(prices[i]); double discount = extract<double>(discounts[i]); item_prices.push_back(price); item_discounts.push_back(discount); }}Copy the code

The Python module definition part is still very straightforward code:

BOOST_PYTHON_MODULE(person)
{
	class_<Person>("Person")
		.def("set_name", &Person::set_name)
		.def("print_info", &Person::print_info)
		.def("set_items", &Person::set_items)
	;	
}
Copy the code

In Python code, you can use the Person class as if it were a Python-defined class:

# -*- coding: utf-8 -*- import sys sys.path.append('.') def test(): Import person p = person.person () p.set_name('Qie') p.set_items([100, 123.456, 888.8], [0.3, 0.1, 0.5]) print p.p rint_info () if __name__ = = "__main__" : the test ()Copy the code

Py++

The module packaging process above still looks a bit boring, with a lot of repetitious work. Can it be done automatically? Py++ provides the ability to automatically generate Boost.Python code, greatly reducing the workload and error probability for modules with a large number of interfaces. For details, see Tutorial

For more on Boost.Python, see GitHub Saber in the Tutorial of the official documentation


Recommended reading:

Python coroutines: from yield/send to async/await/ exploring how to hotfix Python programs how to estimate the memory footprint of a Python object

Reprint please indicate the source: blog.guoyb.com/2017/11/05/…

Please use wechat to scan the qr code below and follow my wechat official account TechTalking. Technology · Life · Thinking:

Back end technology little black room