![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
mrgloom |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
есть пара файлов на питоне *.py
надо их автоматом перевести на с++ или же собрать библиотеку или длл чтобы можно было из с++ вызывать. там подключаются следующие модули
возможно ли? |
|||
|
||||
kosmonaFFFt |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 538 Регистрация: 14.4.2008 Где: Иннополис Репутация: нет Всего: 5 |
Можно заюзать boost::python или просто в C коде создать интерпретатор питона и выполнять скрипты...
-------------------- ![]() |
|||
|
||||
mrgloom |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
это для выполнения участков кода? а можно подключать питоновые библиотеки? интерпретатор нужно с собой таскать?
имеется ввиду самописный интерпретатор? |
||||
|
|||||
mrgloom |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
а с помощью py2exe нельзя сделать dll?
|
|||
|
||||
mrgloom |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
http://docs.python.org/extending/embedding.html
вот нашел, но я не понял с программой надо все таки таскать интерпретатор в таком случае или нет? |
|||
|
||||
rsm |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 999 Регистрация: 16.3.2005 Репутация: нет Всего: 62 |
||||
|
||||
mrgloom |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
ну по-моему это бред, зачем писать парсер+библиотеки, если питон как бы уже имеет среду выполнения. там(выше в постах) вроде бы есть методы как вызывать код питона из кода с++, но для меня остался открытым вопрос нужно ли будет устанавливать интерпретатор питона на машине на которой будет запускаться программа? или например можно как то "вложить" это сразу всё в код, я хочу статическую линковку, т.е. на выходе только 1 .exe. или например надо за собой таскать что то навроде python27.dll или подключать python27.lib? так же не очень понятно как использовать уже готовый код на питоне, ну вот у меня допустим есть 2 .py файла, которые писал не я, но я хочу использовать код который там, там есть import'ы (вроде бы стандартные), но меня все равно это смущает, т.к. т.к. это потянется все в код, как я пониаю? потом там есть классы и функции не понятно как это привязать к классам и функциям на с++. т.е. в идеале я вообще хотел бы так с++ код
т.е. чтобы весь этот питон код был скрыт от меня и лучше бы наверно в отдельную библиотеку. |
||||
|
|||||
kosmonaFFFt |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 538 Регистрация: 14.4.2008 Где: Иннополис Репутация: нет Всего: 5 |
Свой интерпретатор ИМХО писать не надо, достаточно прилинковаться к питоновской билиотеке, не уверен что стандартные питоновские либы просто так заработают, скорее всего придется какие-то файлы питона за собой тянуть...
-------------------- ![]() |
|||
|
||||
mrgloom |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
http://docs.python.org/release/2.5.2/ext/callingPython.html
http://www.codeproject.com/Articles/11805/...n-in-C-C-Part-I http://www.codeproject.com/Articles/11843/...-in-C-C-Part-II вот еще какие-то методы, но все вышеперечисленные вопрсы они не разъяснили. пока попробую shedskin может получится просто перегнать код в с++ UPD: shedskin лажа полная, там столько ограничений, что только головная боль. Это сообщение отредактировал(а) mrgloom - 27.4.2012, 12:11 |
|||
|
||||
mrgloom |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
ладно давайте вообще рассмотрим самый простой пример
как мне вызвать этот код? из с++? т.е. я должен получить что то типа
|
||||
|
|||||
rsm |
|
||||||||
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 999 Регистрация: 16.3.2005 Репутация: нет Всего: 62 |
Парсер писать не надо. Надо будет линковать к своей программе библиотеку Python. Т.е. по сути получится тот же самый интерпретатор, только без интерактивного режима и выполняющий только одну конкретную задачу.
Можно слинковать библиотеку Python статически. Тогда получится один бинарник (интерпретатор), которые будет выполнять передаваемые ему в качестве аргументов (или как-то ещё) скрипты.
Как-то так (исходники примера в аттаче).
Это самый примитивнейший вариант, из которого выпилены все проверки результатов вызовов функций и весь код по освобождению занятой памяти. В нормальном варианте всё должно проверяться и память - освобождаться. И тем не менее, как бы глупо это ни звучало, это вполне полноценный интерпретатор Python. Это сообщение отредактировал(а) rsm - 28.4.2012, 03:26 Присоединённый файл ( Кол-во скачиваний: 2 ) ![]() |
||||||||
|
|||||||||
mrgloom |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
все таки я не очень понял про что вы. это присоединить к проекту на с++ исходный код интерпретатора? так вспомогательные функции (которые лежат в папке Lib) опять же написаны на питоне. насчет кода , в итоге я так и сделал, только мне приходится таскать с собой python27.dll, необходимые файлы .py из Lib и свои .py файлы из которых я вызываю функцию, в принципе и так можно, но хотелось бы все это запаковать в один .exe файл. |
|||
|
||||
rsm |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 999 Регистрация: 16.3.2005 Репутация: нет Всего: 62 |
||||
|
||||
mrgloom |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
пытаюсь вызвать так. кстати так получается вызывать только функции, а как вызывать метод класса?
Это сообщение отредактировал(а) mrgloom - 5.5.2012, 16:22 |
|||
|
||||
rsm |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 999 Регистрация: 16.3.2005 Репутация: нет Всего: 62 |
Для этого сначала нужно создать класс! © К.О. Вот прекрасный, очень маленький и очень простой биндинг к ALSA - там и классы, и callback, и даже python egg ![]() |
|||
|
||||
mrgloom |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
как то там всего много и сложно для меня, не могли бы вы указать хотя бы какие функции стоит посмотреть более пристально или привести пример использования?
|
|||
|
||||
rsm |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 999 Регистрация: 16.3.2005 Репутация: нет Всего: 62 |
Проще разве что "hello, world". pyalsa это хорошо отлаженный и отформатированный код, читается как роман. Нужно просто начать с самого маленького по объёму файла, параллельно заглядывая в официальную документацию по Python/C API.
Какие функции использовать - напрямую зависит от того, что нужно. Если все типы стандартные (int, float, char* и т.д.), это одно. Если типы не стандартные - совершенно другое. Если у функций много аргументов, причём некоторые могут быть заданы по-умолчанию - это третье. В целом, лично я установил для себя всего одно правило: модуль, написанный на С, должен обеспечивать максимально "питонистый" интерфейс. К примеру, если нужно вызвать функцию С, которая принимает аргументом структуру, то в Python эта структура должна быть представлена словарём - естественным для Python типом данных. Если функция С возвращает код ошибки, нужно не возвращать в Python этот код ошибки, а генерировать исключение - потому что для Python это, опять же, наиболее естественное и ожидаемое поведение. Причём исключения должны быть по возможности стандартными. Например, некорректное значение аргумента функции => генерируем ValueError. Если подходящего класса исключений в стандартной библиотеке Python нет, то нужно создать свой класс и использовать его. И так далее, в том же духе. "Питонистость" во всём модуле. Что касается примеров, то я и сам нигде не мог их найти. Просто брал маленькие краткие биндинги и смотрел, как они написаны. Читал документацию. В этом Сила открытого софта ![]() Это сообщение отредактировал(а) rsm - 24.5.2012, 17:08 |
|||
|
||||
Karadul |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 378 Регистрация: 18.5.2006 Репутация: нет Всего: 1 |
Я больше сталкивался с тем, что делается копия сишного апи на питоне(_winreg/pycurl), а для него уже пишутся обертки. |
|||
|
||||
rsm |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 999 Регистрация: 16.3.2005 Репутация: нет Всего: 62 |
Увы, не всегда возможно. Например, когда C оперирует сложными структурами - тут без вариантов, нужно сразу писать конвертацию "структура" <=> "словарь". Другой вариант - когда C реализует квази-ООП. Ещё вариант - асинхронная обработка данных. В общем, каждый случай индивидуален. Но в целом да, согласен - на некоторых задачах быстрее и проще сначала написать интерфейс модуля "в стиле С", а потом уже добавить ему "питонистость" средствами самого Python. |
|||
|
||||
Karadul |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 378 Регистрация: 18.5.2006 Репутация: нет Всего: 1 |
Только добавлять эту "питонистость" - работа, видимо, неблагодарная, поэтому о ней часто забывают. "Питонистость" (а точнее, ООП-шность - "жавоидность" будет выглядеть почти так же) состоит не из структур данных, а, например, вместо кодов возврата должны бросаться исключения. И этому не всегда следуют даже встроенные модули питона (poplib/imaplib возвращают кортежи с содержимым, которое хрен запомнишь). Еще программа не должна грохаться с сегфолтом, а бросать вменяемое исключение, поэтому, например, кто-то должен проверять типы параметров - или нативный модуль, или питоновая обертка (wireshark через lua api грохался на ура, если ему подсунуть не тот обьект). А в чем проблема перевести квази в не квази для питона? Ну и само собой разумеется, что структуры данных должны конвертироваться в те, которые есть на питоне. Асинхронная обработка так же реализуется через коллбеки. Ключевые моменты "питонистости" оберток - это:
Это сообщение отредактировал(а) Karadul - 26.5.2012, 17:14 |
|||
|
||||
rsm |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 999 Регистрация: 16.3.2005 Репутация: нет Всего: 62 |
||||
|
||||
Karadul |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 378 Регистрация: 18.5.2006 Репутация: нет Всего: 1 |
Тем не менее, _winreg попал в стандартную библиотеку питона. Хотя нормальная обертка для него - строк на 20. А что со ними? Сишкопроблемы ![]() |
|||
|
||||
rsm |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 999 Регистрация: 16.3.2005 Репутация: нет Всего: 62 |
В асинхронных модулях нужно быть предельно внимательным к контролю времени жизни объектов, т.к. по факту никакого достаточно прямого способа обнаружить утечки памяти нет. Добавим к этому GIL - и получаем феерическую головную боль. Поэтому простой обёрткой уже не обойтись - нужно создавать объекты и манипулировать ими со стороны С. В противном случае поведение становится трудно предсказуемым. |
|||
|
||||
Karadul |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 378 Регистрация: 18.5.2006 Репутация: нет Всего: 1 |
А чем плох именно GIL?
Можно сделать так, что обьектом займется питоновский мусоровоз? |
|||
|
||||
rsm |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 999 Регистрация: 16.3.2005 Репутация: нет Всего: 62 |
Проблема не в GIL как таковом, проблема в скрещивании С и Python. Требуется уделить большое внимание тому, чтобы объект, убранный GC в Python, не был повторно освобождён из С. Или наоборот - чтобы Python не пытался использовать объект, уже освобождённый в С. Из-за наличия в интерпретаторе мощных оптимизаций расхода памяти, по адресу, который уже освободили, сразу же могут оказаться совершенно другие данные, которые Python и/или С могут воспринять как должное. Такие ошибки сложнее всего отловить. Или, к примеру, гонка за ресурсы - что получится, если Python уже заблокировал GIL, а часть со стороны С изменила какой-то объект? Конечно, средства для устранения подобных ситуаций предусмотрены, но за ними нужно пристально следить. Да и то нет полной гарантии отсутствия ошибок. |
|||
|
||||
Karadul |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 378 Регистрация: 18.5.2006 Репутация: нет Всего: 1 |
Ыыыы, а это когда из си вызывается питон или модули на питоне написаны на си?
|
|||
|
||||
rsm |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 999 Регистрация: 16.3.2005 Репутация: нет Всего: 62 |
||||
|
||||
Karadul |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 378 Регистрация: 18.5.2006 Репутация: нет Всего: 1 |
||||
|
||||
rsm |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 999 Регистрация: 16.3.2005 Репутация: нет Всего: 62 |
||||
|
||||
Karadul |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 378 Регистрация: 18.5.2006 Репутация: нет Всего: 1 |
А зря. Лепят всюду этот луа, в котором ни стандартной библиотеки искаропки, ни даже нормального ООП.
|
|||
|
||||
mrgloom |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
допустим использую PyRun_SimpleString
возник вопрос, как контролировать выполнилась ли строчка кода или нет? ну допустим, если разработчиком питон кода сделано так, что функция скажем возвращает 0 или 1 в зависимости от того выполнилась или нет, то можно просто получать это возвращаемое значение. а если это не предусмотрено? теортетически даже непонятно, что в консоль питона должно вывестись. а если чего то не хватает, как у меня было с import _socket или еще какая ошибка? тем более вообще не понятно можем ли мы как то отслеживать, что выводится в консоль питона. |
|||
|
||||
rsm |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 999 Регистрация: 16.3.2005 Репутация: нет Всего: 62 |
На время отладки возвращать более развёрнутый результат, плюс вести лог всех вызовов. Только не в консоль, а в файл - в консоли никаких сообщений из модуля на С не будет. Если нужна более продвинутая отладка - помогут gdb и Python, собранный с отладочной информацией.
Не предусмотрено кем?
Поможет strace. |
||||
|
|||||
Karadul |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 378 Регистрация: 18.5.2006 Репутация: нет Всего: 1 |
||||
|
||||
rsm |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 999 Регистрация: 16.3.2005 Репутация: нет Всего: 62 |
||||
|
||||
Karadul |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 378 Регистрация: 18.5.2006 Репутация: нет Всего: 1 |
Ну так тоже ведь можно?
|
|||
|
||||
rsm |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 999 Регистрация: 16.3.2005 Репутация: нет Всего: 62 |
||||
|
||||
mrgloom |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 8.6.2011 Репутация: нет Всего: нет |
ну вот например, загружаю свою длл, там в конструкторе стоит эта функция, падает на PyRun_SimpleString, причем что не так непонятно, прост опишет triggered a breakpoit, это если запускаю из дебага, а если в релизе, то просто моя длл-ка не грузится, getlasterror выдает ошибку 998. (Неверная попытка доступа к адресу памяти.) |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Python: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |