LINUX.ORG.RU

Получить значение строки через C-API

 ,


0

1

Есть некая программа, которая использует Python через C-API. Подскажите как в ней получить значение строки? Допустим, после выполнения простой строки при помощи PyRun_SimpleString образовалась текстовая переменная test:

Py_Initialize();
PyObject *module = PyImport_AddModule("__main__");
qDebug() << "python=" << PyRun_SimpleString("import math\ntest = 'haha'\nprint('%d -> %s' % (math.sqrt(144), test))\n");
PyObject *_out = PyObject_GetAttrString(module, "test");
char *c_str = PyByteArray_AsString(_out);
QString out = QString(c_str);
qDebug() << "out=" << out;
Py_Finalize();
Как получить значение этой строки?

Вышеприведенный пример не падает, но на выходе пустая строка. Есть еще способ через PyUnicode_FromString но опять же он не работает. Вообще непонятно, может PyObject_GetAttrString это неверный путь? PySys_GetObject тоже не дает результата совместно с PyUnicode_FromString.

Если кто работал с C-API, подскажите пожалуйста, уже второй день гуглю, но ни примеры из инета ни документация не помогает разобраться. Хотя странно, вроде самая простая задача.

qt захавало твой мозг, жду когда ты заплачешь и воткнешь в пузо своей программы lua

--- old 2017-02-06 17:05:24.000000000 +0300
+++ new 2017-02-06 17:07:26.000000000 +0300
@@ -1,8 +1,8 @@
 Py_Initialize();
 PyObject *module = PyImport_AddModule("__main__");
-qDebug() << "python=" << PyRun_SimpleString("import math\ntest = 'haha'\nprint('%d -> %s' % (math.sqrt(144), test))\n");
+qDebug() << "python=" << PyRun_SimpleString("import math\ntest = b'haha'\nprint('%d -> %s' % (math.sqrt(144), test))\n");
 PyObject *_out = PyObject_GetAttrString(module, "test");
-char *c_str = PyByteArray_AsString(_out);
+char *c_str = PyBytes_AsString(_out);
 QString out = QString(c_str);
 qDebug() << "out=" << out;
 Py_Finalize();
это для python 3.x

hizel ★★★★★
()
Ответ на: комментарий от hizel
qDebug() << "python=" << PyRun_SimpleString("import math\ntest = 'haha'\nprint('%d -> %s' % (math.sqrt(144), test))\n");
PyRun_SimpleString("test = str.encode(test)");
PyObject *_out = PyObject_GetAttrString(module, "test");
char *c_str = PyBytes_AsString(_out);
QString out = QString(c_str);
qDebug() << "out=" << out;

Спасибо! Способ работает. Я нашел как его улучшить: можно задавать test = 'haha', а затем test = str.encode(test) и оно уже будет выходить как PyBytes_AsString.

Спасибо за помощь!

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от hizel

Хватит тереть комменты! В снесенном посте, ты правильно нашел некоторую боль в районе unicode и если не хочешь разбираться с пистоном, ничего не получится, придется разбираться :P Qt принимает utf8? присунь через PyUnicode_AsUTF8AndSize например.

hizel ★★★★★
()
Ответ на: комментарий от hizel

Прошу прощения что стер, там был вопрос как обычную строку сделать как b', нашел что через encode... Да, UTF-8 понимается. Сделал

char *c_str = PyUnicode_AsUTF8(_out);
На выходе пусто. Как строку test загнать в Unicode?

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

На выходе, не 'пусто', а NULL. В варианте с byte, не получится красиво присунуть русский язык. Проверяй через PyUnicode_Check.

PyRun_SimpleString(«test = b'haha'»); это byte, на нем PyUnicode_AsUTF8 не заработает, для PyUnicode_AsUTF8 нужно просто PyRun_SimpleString(«test='haha'»);

И да, открой уже документацию, она норм.

hizel ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft
qDebug() << "python=" << PyRun_SimpleString("import math\ntest = 'haйфыha'\nprint('%d -> %s' % (math.sqrt(144), test))\n");
PyRun_SimpleString("test = test.encode('utf-8')");
PyObject *_out = PyObject_GetAttrString(module, "test");
char *c_str = PyBytes_AsString(_out);
QString out = QString(c_str);
qDebug() << "out=" << out;
Py_Finalize();

Почему-то на Linux работает и так, эти байты уже выходят как UTF-8, и в qDebug я вижу кириллицу. Возможно это не кроссплатформенное решение.

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от hizel

Спасибирую! Без b' и без encode PyUnicode_AsUTF8 срабатывает как надо и out не пустой!

qDebug() << "python=" << PyRun_SimpleString("import math\ntest = 'haйфыha'\nprint('%d -> %s' % (math.sqrt(144), test))\n");
PyObject *_out = PyObject_GetAttrString(module, "test");
char *c_str = PyUnicode_AsUTF8(_out);
QString out = QString(c_str);
qDebug() << "out=" << out;
Вроде подобный способ я проверял, наверное в другом месте налажал и отбросил этот рабочий вариант...

I-Love-Microsoft ★★★★★
() автор топика
Последнее исправление: I-Love-Microsoft (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.