Используем Python в своей программе

Используем Python в своей программе

При разработке прикладных программ иногда возникает необходимость предоставить пользователю какую-то достаточно гибкую, но простую систему для управления программой.

Есть множество вариантов реализации таких систем, но одним из наиболее простых является встраивание в приложение интерпретатора скриптовых языков.

Реализацией этого варианта мы сегодня и займемся. В качестве скриптового языка был выбран Python из-за достаточно большого спектра применения.

Он кроссплатформенный, существуют официальные версии для Windows, Linux и MacOS. В конце концов, о мощи и потенциале этого языка может говорить хотя бы тот факт, что он используется в небезызвестной корпорации Google как основной язык программирования.

На старт

Качаем с www.python.org последний релиз интерпретатора языка и устанавливаем его куда-нибудь. Проверяем наличие следующих файлов:

Python\libs\python31.lib (или libpython31.a, если вы используете gcc)

Если этих файлов нет, нужно скачать с официального сайта исходники интерпретатора и распаковать их куда-нибудь. Создайте проект в любой IDE (например, MS VS 2005) и пропишите в настройках подключаемых модулей пути к папкам с этими файлами.

Простенькая программка

#include int main(int argc, char *argv[])

Теперь ее обсудим.

Первым делом подключается Python.h для получения доступа к Python API.

Перед работой с интерпретатором необходимо обязательно вызывать Py_Initialize, после ее окончания Py_Finalize. Один из способов вызвать на выполнение нужный скрипт – это функция PyRun_SimpleString. Она принимает в качестве параметра строку со скриптом и выполняет. В приведенном примере функция выведет на экран текущее время. Однако в большинстве случаев этого недостаточно.

Получение результата выполнения функции

Предположим, что нам нужна программа для построения графиков мат. функций. Если это простая функция вроде у = x + 1 ― cos(x), то проблем с вводом не возникнет, достаточно написать простой парсер выражений на основе обратной польской записи. Но функций могут быть и более сложные, например:

  • Передаем параметр функции, написанной на Python-е
  • Выполняем её
  • Получаем результат

def func(x): if x > 3: return x + 1 elif 1 < x <= 3: return 0 else: return x ** x

Функция, вызывающая скрипт с функцией y(x) из модуля:

double compute(double x)

Обсудим использованные функции, не особо вдаваясь в подробности, т. к. цель данной статьи состоит в рассказе об основных моментах встраивания Python’а в приложения. Для получения более подробных сведений можно почитать документацию на официальном сайте.

Функции вида Py*_From* позволяют преобразовывать встроенные типы С/C++ во внутренние типы Python’а. Т. е., например, PyUnicode_FromString преобразует свой строковый параметр во внутреннее юникодовое представление Python’а для того, чтобы интерпретатор языка смог потом с ним (с параметром) работать. Функции вида Py*_As* имеют обратное действие (т.е. преобразовывают типы из внутреннего представления интерпретатора во встроенные типы C/C++).

PyImport_Import позволяет получить доступ к функциям модуля, имя которого указывается в качестве параметра. Тип параметра, разумеется, нужно предварительно преобразовать во внутреннее представление.

Py_DECREF ― макрос, высвобождающий память, занятую используемыми интерпретатором данными. Этот макрос отличается от Py_XDECREF тем, что последний может принимать нулевые значения в качестве параметра. Например, следующий фрагмент преобразует строку «mod» во внутренний тип Python’а и загружает нужный модуль.

pName = PyUnicode_FromString("mod"); pModule = PyImport_Import(pName); Py_DECREF(pName);

После этого объект, содержащий строку, более не нужен, поэтому память очищается при помощи Py_DECREF.

PyObject_GetAttrString возвращает указатель на функцию из модуля, указанного в качестве первого параметра с именем, указанным в качестве второго.

Для передачи параметров функциям используются так называемые «tuples». Далее для простоты будем называть их кортежами. Кортежи – наборы определенного количества значений разных типов. Для создания нового кортежа используется функция PyTuple_New с указанием нужного числа передаваемых аргументов. Потом кортеж заполняется значениями при помощи PyTuple_SetItem, первый аргумент которой – кортеж, второй – порядковый номер аргумента, а третий – его значение. После этого можно вызвать функцию PyObject_CallObject, передав ей функцию и кортеж аргументов. Теперь организация ввода пользователем исходных данных не составляет проблемы.

📎📎📎📎📎📎📎📎📎📎