Hi all!!!
- Как получить ссылку на python функцию и какой будет ее тип?
- Как ее вызвать из C++?
- И как получить ссылку на python объект?
Хотелось бы средствами boost::python.
Есть python скрипт в котором определана pyFunc() и строка strA:
import sys, os
sys.path.append(os.getcwd())
strA = "python string"
def pyFunc():
print('python: pyFunc()')
return True
Есть C++ код, который выполняет этот код и забирает из окружения python что то:
/* pytest.cpp */
/* build: g++ -std=c++1y -fPIC -I/usr/include/python3.4 -lboost_python -lpython3.4m pytest.cpp */
/* bould: g++ -std=c++1y -fPIC -I/usr/include/python3.4 -lboost_python-py34 -lpython3.4m pytest.cpp */
#include <string>
#include <iostream>
#include <boost/python.hpp>
using namespace boost::python;
int main() {
try {
Py_Initialize();
object main_module = import("__main__");
object main_namespace = main_module.attr("__dict__");
object pyScript = exec_file("test.py", main_namespace);
/* Тут хотелось бы получить ссылку на python строку, а не копировать ее в C++ строку s: */
std::string s = extract<std::string>(main_namespace["strA"]);
/* можно так: s = extract<std::string>(main_module.attr("strA")); */
std::cout << "strA in C++ space: "<< s << std::endl;
/* Второй вариант, */
/* тут тоже хочу иметь ссылку на d["strA"], не пойму как привезти тип к std::string&: */
dict d = extract<dict>(main_module.attr("__dict__"));
d["strA"] += " +changed in cpp";
object pyScript1 = exec("pyFunc()\n" /* это вызов pyFunc() из python кода */
"strA += ' +changed in python'\n"
, main_namespace);
/* Вот именно поэтому нужна ссылка на pyhon строку: */
s = extract<std::string>(main_namespace["strA"]);
std::cout << "strA in C++ space: "<< s << std::endl;
/* ********************************************************** */
/* И самый главный вопрос: как мне получить ссылку на pyFunc, */
/* да еще и вызвать ее из C++ кода??? */
/* ********************************************************** */
/* Note that at this time you must not call Py_Finalize() to stop the interpreter. This may be fixed in a future version of boost.python. */
/* http://www.boost.org/doc/libs/master/libs/python/doc/html/tutorial/tutorial/embedding.html */
/* Py_Finalize(); */
} catch(error_already_set const &) {
if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) {
/* handle ZeroDivisionError specially */
} else {
/* print all other errors to stderr */
PyErr_Print();
}
}
}
Заранее благодарен за Ваши ответы.
UPD: С вызовом функции разобрался. Не пойму только какой тип. И остался вопрос со ссылкой на strA.
auto fptr1 = d["pyFunc"];
std::function<bool()> fptr2(d["pyFunc"]);
std::cout << bool(fptr1()) << " " << fptr2() <<std::endl;
std::cout << typeid(fptr1).name() << std::endl;