Отправляет email-рассылки с помощью сервиса Sendsay

Встраиваемый Pyton

Прочел, что Pyton легко встраивается в качестве интерпретирующего языка
в программы, написанные на другом языке, но нигде не нашел ни примера,
ни указания как это сделать.

Может кто подскажет?

Нужна возможность работать из некого программного продукта - обращаться
к интерпретатору Pyton и получать результаты его работы. А то и более
сложное взаимодействие.

Ответы:

В Thu, 4 Jun 2009 11:17:44 +0400
Крохин Анатолий Александрович <akroh***@b*****.ru> пишет:

Нашел-таки как встроить питон:

8<#include <stdio.h>
#include <Python.h>

int main()
{
int result;
PyObject *pstr, *pmod, *pdict;

//инициализация интерпретатора
Py_Initialize();

pmod = PyImport_ImportModule("sys");
pdict = PyModule_GetDict(pmod);

//вычисление выражения из строки
pstr = PyRun_String("3+4*5",Py_eval_input,pdict,pdict);
//извлечение данных из объекта Python и вывод результата
PyArg_Parse(pstr,"i",&result);
printf("%i\n",result);

//удаление созданного Python объекта, завершение интерпретатора и выход
Py_DECREF(pstr);
Py_Finalize();

return 0;
}

8<Но как теперь подключить несколько модулей? Мне-то нужен re

Hello.

Непонятно какие именно проблемы вылезают с несколькими модулями.
Я дополнил вашу болванку вызовами re.search(...).start() и os.path.getsize().
Обратите внимание на формат вызова: не "re.search().start()", а
"search().start()" + правильный dict от модуля. Надеюсь, поможет:

danil@desk $ cat ./test1.c
#include <stdio.h>
#include <Python.h>

int main()
{
int result;
PyObject *pstr, *pmod, *pdict;

//инициализация интерпретатора
Py_Initialize();

PyObject *main = PyImport_AddModule("__main__");
PyObject* main_dict = PyModule_GetDict( main );

pmod = PyImport_ImportModule("sys");
pdict = PyModule_GetDict(pmod);

PyObject *re_mod = PyImport_ImportModule("re");
PyObject *re_dict = PyModule_GetDict(re_mod);
PyObject *re_str;

PyObject *os_mod = PyImport_ImportModule("os");
PyObject *os_dict = PyModule_GetDict(os_mod);
PyObject *os_str;

//вычисление выражения из строки
const char* pstr_cmd = "3+4*5";
pstr = PyRun_String(pstr_cmd, Py_eval_input, pdict, pdict);
if ( pstr == NULL )
PyErr_Print();

const char* restr_cmd = "search(\"abc\", \"asabcadafag\").start()";
re_str = PyRun_String(restr_cmd, Py_eval_input, main_dict, re_dict);
if ( re_str == NULL )
PyErr_Print();

const char* osstr_cmd = "path.getsize(\"/usr/bin/python\")";
os_str = PyRun_String(osstr_cmd, Py_eval_input, main_dict, os_dict);
if ( os_str == NULL )
PyErr_Print();

//извлечение данных из объекта Python и вывод результата
if (pstr != NULL ) {
PyArg_Parse(pstr,"i",&result);
printf("%s evaluated to %i\n", pstr_cmd, result);
}

if ( re_str != NULL ) {
PyArg_Parse(re_str,"i",&result);
printf("%s evaluated to %i\n", restr_cmd, result);
}

if ( os_str != NULL ) {
PyArg_Parse(os_str,"i",&result);
printf("%s evaluated to %i\n", osstr_cmd, result);
}

//удаление созданного Python объекта, завершение интерпретатора и выход
Py_DECREF(pstr);
Py_DECREF(re_str);
Py_DECREF(os_str);
Py_Finalize();

return 0;
}
danil@desk $ gcc `python-config --cflags` `python-config --ldflags` ./test1.c
danil@desk $ ./a.out
3+4*5 evaluated to 23
search("abc", "asabcadafag").start() evaluated to 2
path.getsize("/usr/bin/python") evaluated to 6080

On Thu, 4 Jun 2009 13:07:27 +0400
Крохин Анатолий Александрович <akroh***@b*****.ru> wrote about "Re: Встраиваемый
Pyton":

-*Название листа "Linux: разрешение вопросов, перспективы и общение";
Написать в лист: mailto:comp.soft.linux.discuss-list@subscribe.ru
Адрес правил листа http://subscribe.ru/catalog/comp.soft.linux.discuss/rules
Номер письма: 36139; Возраст листа: 2142; Участников: 1382
Адрес сайта рассылки: http://www.linuxrsp.ru
Адрес этого письма в архиве: http://subscribe.ru/archive/comp.soft.linux.discuss/msg/868922

Ответить   Fri, 5 Jun 2009 02:42:20 +0400 (#868922)

 

В Fri, 5 Jun 2009 02:42:20 +0400
Danila Vassenkov <vadani***@y*****.ru> пишет:

Огромное спасибо! Буду разбираться.

2009/6/4 Крохин Анатолий Александрович <akroh***@b*****.ru>:

Мы этим пользуемся постоянно. Рецепты как это сделать довольно
подробно описаны в документе Extending and Embedding Python, глава 5.
Там же есть и образцы кода.
Некоторое затруднение может вызвать компоновка с библиотеками Python,
мы в результате собрали собственный экземпляр Python с динамической
библиотекой libpython, но это наше частное решение, продиктованное
необходимостью распространять программы в независимой от версии
дистрибутива линукс форме. Так что. нормальным решением будет
воспользоваться пакетом python2.x-dev, с которым устанавливаются и
заголовочные файлы, и статические библиотеки.

Ответить   Thu, 4 Jun 2009 14:37:22 +0400 (#868455)

 

В Thu, 4 Jun 2009 14:37:22 +0400
Vladimir Efremov <vefrem***@g*****.com> пишет:

Как раз в этом у меня загвоздка

2009/6/4 Крохин Анатолий Александрович <akroh***@b*****.ru>:

вот небольшой пример:

код на с++ (pc.cpp):
#include <Python.h>
#include <iostream>
using namespace std;
int
main(int argc, char *argv[])
{
cerr << "Starting" << endl;
PyObject *pArgs, *pValue1, *pValue2;
int i1 = 3, i2 = 4;

Py_Initialize();
PyObject *pName = PyString_FromString("mod");
PyObject *pModule = PyImport_Import(pName);
cerr << "After import" << pModule << endl;
PyObject *pFunc = PyObject_GetAttrString(pModule, "f");
cerr << "pFunc" << pFunc << endl;
pArgs = PyTuple_New(2);
pValue1 = PyInt_FromLong(i1);
pValue2 = PyInt_FromLong(i2);
PyTuple_SetItem(pArgs, 0, pValue1);
PyTuple_SetItem(pArgs, 1, pValue2);
cerr << "Before calling" << endl;
PyObject *pValue = PyObject_CallObject(pFunc, pArgs);
cout << "Result: " << PyInt_AsLong(pValue) << endl;
Py_Finalize();
return 0;
}

Модуль на питоне:
import xmlrpclib
def f(a1, a2):
print "working", a1, a2
st = xmlrpclib.ServerProxy("http://ubuntu:8000")
print st.getServerName()
return a1 + a2

(здесь xmlrpclib нужен только для иллюстрации, что можно сложный
модуль, работающий с сетью проимпортировать)

Теперь собираем (руками) с системным питоном 2.5:
[efremov@ubuntu Python]$ g++ -c -I /usr/include/python2.5 pc.cpp
[efremov@ubuntu Python]$ g++ pc.o -o pc -Xlinker -export-dynamic
-L/usr/lib -l python2.5
и запускаем:
[efremov@ubuntu Python]$ PYTHONPATH=. ./pc
Starting
After import0xb7b6032c
pFunc0xb7b2c994
Before calling
working 3 4
RV_DBServer (9139; 9099)
Result: 7

Работает! А вот пример с PyRun_SimpleString почему-то падает. Некогда
разбираться.

Ответить   Thu, 4 Jun 2009 17:13:23 +0400 (#868731)

 

В Thu, 4 Jun 2009 17:13:23 +0400
Vladimir Efremov <vefrem***@g*****.com> пишет:

Предыдущее письмо отправил случайно.

В Thu, 4 Jun 2009 17:13:23 +0400
Vladimir Efremov <vefrem***@g*****.com> пишет:

Мне нужен на C. Но, думаю, принципиальной разницы нет. Разберусь.

Огромное спасибо!

Hello.

Для C/C++ пример описан в документации:
http://docs.python.org/extending/embedding.html
http://docs.python.org/c-api/index.html

С остальными языками это наверняка не сложнее, например, гугль
на запрос "embedding python <you lang>" дает много результатов.

Совсем экзотику можно попробовать подружить через линковку с C-кодом с обеих
сторон. В любом случае, форк для "python -c" сработает везде и всегда :)

On Thu, 4 Jun 2009 11:17:44 +0400
Крохин Анатолий Александрович <akroh***@b*****.ru> wrote about "Встраиваемый Pyton":

-*Название листа "Linux: разрешение вопросов, перспективы и общение";
Написать в лист: mailto:comp.soft.linux.discuss-list@subscribe.ru
Адрес правил листа http://subscribe.ru/catalog/comp.soft.linux.discuss/rules
Номер письма: 36136; Возраст листа: 2141; Участников: 1382
Адрес сайта рассылки: http://www.linuxrsp.ru
Адрес этого письма в архиве: http://subscribe.ru/archive/comp.soft.linux.discuss/msg/868489

Ответить   Thu, 4 Jun 2009 13:53:57 +0400 (#868489)

 

В Thu, 4 Jun 2009 13:53:57 +0400
Danila Vassenkov <vadani***@y*****.ru> пишет:

Это я уже нашел. Но тут пример в стиле "Hello! World!!!" Т. е. тут
используется только один библиотечный модуль. А как несколько? Мне,
например, нужно использовать re.

Так и предполагалось изначально.