Пример кода, который вы используете, будет работать только тогда, когда ваш код Python возвращает объект, который может быть представлен типом C ++ int
. Такое поведение вызвано этой строкой вашего кода:
int boostOutputStr = extract<int>(result);
Общая проблема, с которой вам приходится сталкиваться, заключается в том, что C ++ является строго типизированным языком, а Python - нет. Оператор python (или вызов функции python) может вернуть объект любого типа, и один вызов функции может вернуть объект другого типа, чем следующий вызов той же функции. В C ++ возвращаемый тип функции (а также типы аргументов) должны быть четко определены. Тем не менее, C ++ предоставляет шаблоны для случаев, когда вы хотите быть более гибкими. Определив одну шаблонную функцию (и хорошим примером является функция извлечения boost :: python), вы можете использовать эту функцию для конфигураций разных типов. Тем не менее, код функции вашего шаблона будет создан компилятором для каждого типа, с которым вы его используете. То есть метод шаблона избавляет вас от утомительной работы копирования и вставки, а затем изменения кода для всех типов, с которыми вы его используете. Компилятор делает это для вас. Но все типы должны быть четко определены во время компиляции. Вы не можете заставить функцию возвращать иногда int
, а иногда string
в зависимости от ввода пользователя. Вот для чего подходят языки сценариев, такие как Python или, возможно, другие языки высокого уровня. В C ++ все типы должны быть установлены во время компиляции кода.
Так что же делать в вашей ситуации?
Вы можете либо заставить pythonCallBackFunc
вернуть result
напрямую, не преобразовывая его в int
. Таким образом, возвращаемое значение будет иметь тип object
(из boost :: python) и будет представлять объект Python. Вы можете преобразовать это с extract<>
в любой тип, который вам понадобится позже в вашем коде. (Я предполагаю, что вы действительно хотите, чтобы возвращаемое значение вашего выражения Python передавалось обратно в ваш код, а не распечатывалось через cout
все время.)
Или вы можете сделать свою функцию pythonCallBackFunc
также шаблонной функцией.
template<class ReturnType>
void pythonCallBackFunc(string inputStr){
Py_Initialize();
try
{
str boostInputStr(inputStr.c_str());
object result = eval(boostInputStr);
return extract<ReturnType>(result);
//Py_Finalize() #not calling because of the boost.python
}
catch(error_already_set const &)
{
//do somthing
}
}
... в этом случае вам придется вызывать его с соответствующим типом, как, например,
pythonCallBackFunc<int>(inputStr);
Надеюсь, это поможет вам.