Python как лучший в миреклейЯзык (хм, конечно, лучший язык в мире — это PHP==), используя простоту Python и эффективность C++, можно решить 99% проблем~
В целом взаимодействие между Python и C++ делится на два случая:
- Расширение Python с помощью C++: когда в проекте Python возникает узкое место в производительности, извлеките часть узкого места и используйте C++, чтобы инкапсулировать его в модуль (то есть библиотеку), который Python может вызывать;
- Встраивание 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:
Бэкенд-технологии «черный дом»