Member 13020023 Ответов: 1

Вызов Python eval из C++.


Я пытаюсь вычислить строку в C++ с помощью Python C API.

Что я уже пробовал:

Я уже пробовал это сделать:

std::string s = "2 + 2 * 4";
PyObject* module = PyImport_AddModule("__main__");
if (module)
{
    PyObject* func = PyObject_GetAttrString(module, "eval");

    PyObject* returnValue = PyObject_CallObject(func, PyUnicode_FromString(s.c_str()));

    std::cout << PyLong_AsLong(returnValue);
}


Но вместо 10 я получаю -1.

Почему это так?

1 Ответов

Рейтинг:
7

Richard MacCutchan

PyObject* module = PyImport_AddModule("__main__");

__main__ это не имя модуля и может существовать в тысячах модулей. И eval это встроенная функция, а не часть какого-либо импорта. Попробуйте использовать __builtins__ как имя модуля.


Member 13020023

Поэтому я немного изменил его на:

std::строка s = "2 * 2";
PyObject* module = PyImport_AddModule("__builtins__");
if (модуль)
{
PyObject* func = PyObject_GetAttrString(модуль, "eval");

PyObject* args = PyTuple_New(1);
PyTuple_SetItem(аргументы, 0, PyUnicode_FromString(С. c_str()));

PyObject* returnValue = PyObject_CallObject(func, args);

std::cout << PyLong_AsLong(returnValue);
}

, но он бросает это исключение в cout:
Исключение, вызванное в 0x00007FFD5E9325CE (python37.dll) в Python CAPI.exe: 0xC0000005: нарушение доступа к местоположению чтения 0x0000000000000008.

Richard MacCutchan

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

Richard MacCutchan

Я только что попробовал этот код и звонок на PyObject_GetAttrString(module, "eval"); возвращать null. Так что, похоже, вы не можете получить адрес eval таким образом.

Member 13020023

Тааак, у тебя есть какие-нибудь идеи, как заставить его работать?

Richard MacCutchan

Нет, я никогда не пробовал использовать Python из C, пока не увидел этот вопрос.

Member 13020023

Может быть, вы знаете какой-нибудь другой способ вычисления строки в C++?

Richard MacCutchan

Да, вам нужно будет написать код самостоятельно. Существует множество примеров математических калькуляторов на основе стека в C/C++, которые Google найдет для вас.

Member 13020023

Спасибо! Я написал оценщик C++, используя синтаксический анализ. Я использовал обратную польскую нотацию, и она отлично работает!