Пройти Python и C++

задняя часть Python API C++
Пройти Python и C++

Python как лучший в миреклейЯзык (хм, конечно, лучший язык в мире — это PHP==), используя простоту Python и эффективность C++, можно решить 99% проблем~

В целом взаимодействие между Python и C++ делится на два случая:

  1. Расширение Python с помощью C++: когда в проекте Python возникает узкое место в производительности, извлеките часть узкого места и используйте C++, чтобы инкапсулировать его в модуль (то есть библиотеку), который Python может вызывать;
  2. Встраивание Python в C++: когда ожидается частое изменение требований к некоторым функциям в проекте C++ и ожидается более высокая гибкость, реализуйте эти функции в Python и вызывайте их в C++.Эта статья кратко представит один из подходов в первой части.

Boost.Python

Boost — это огромная сокровищница, которая предоставляет эту необходимую нам функциональность. Кроме того, во многих библиотеках Boost Boost.Python уже используется по умолчанию, поэтому он хорошо протестирован.

Установить

Большинство функций Boost предоставляются в виде заголовочных файлов и не требуют установки, однако есть также несколько функций, требующих ручной компиляции. К сожалению, Boost.Python также является одним из них.

Ссылаться наGetting Started on Unix VariantsПятая часть контента, вы можете установить Boost.Python. После завершения установки вы можете увидеть соответствующие файлы so в соответствующем каталоге (мой находится в /usr/local/lib).

Hello World

Реализуйте модуль на C++, который при вызове в Python возвращает определенную строку.

#include <boost/python.hpp>

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

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

Слишком просто, код в принципе все объясняет~

Скомпилируйте его в виде динамической библиотеки:

 
g++ -I /usr/include/python2.7/ -fPIC -shared -o hello_boostpy.so hello_boostpy.cc -lboost_python

В настоящее время вы можете использовать ldd, чтобы узнать, может ли hello_boostpy.so найти libboost_python.Если вы не можете его найти, вам нужно вручную добавить его путь в переменную среды LD_LIBRARY_PATH или использовать команды, связанные с ldconfig.

Затем вы можете использовать библиотеку hello_boostpy в Python:

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


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


if __name__ == "__main__":
    print test()

Expose Class

Затем мы добавляем класс в модуль, реализованный на C++, и пытаемся передать объект типа списка Python в направлении C++.

Класс С++:

#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;
};

Среди них тип списка на стороне Python имеет соответствующую реализацию boost::python::list в Boost.Python (соответственно, dict, tuple и другие типы имеют соответствующие реализации). В set_items мы будем использовать 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);
	}
}

Часть определения модуля Python по-прежнему очень интуитивно понятна:

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)
	;	
}

В коде Python вы можете использовать класс Person точно так же, как класс, определенный Python:

# -*- 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.print_info()


if __name__ == "__main__":
    test()

Py++

Описанный выше процесс инкапсуляции модуля все еще выглядит немного скучно, и есть много мест, где работа повторяется. Так можно ли это сделать автоматически? Py++ предоставляет возможность автоматически генерировать для вас код, связанный с Boost.Python.Для модулей с большим количеством интерфейсов это может значительно снизить рабочую нагрузку и вероятность ошибок. Для конкретного использования см.Tutorial

Дополнительные сведения о Boost.Python см.официальная документация Tutorial
См. связанный кодGitHub saber


Рекомендуемое чтение:

Сопрограммы Python: от yield/send к async/await/
Узнайте, как исправлять программы Python
Как оценить объем памяти объекта Python

Пожалуйста, укажите источник:blog.Mandarin.com/2017/11/05/…

Добро пожаловать в WeChat для сканирования приведенного ниже QR-кода. Подпишитесь на мою общедоступную учетную запись WeChat TechTalking, Technology·Life·Thinking:
后端技术小黑屋Бэкенд-технологии «черный дом»