3

I'm trying to execute Python code from c++ that will define a Python function and pass it back to c++ so it can be called back from there. That works fine but the problem is I can't provide the Python function with the namespace it had when it was originally defined.

struct MyClass {
    void log(const std::string & s)
    {
        cout << s << endl;
    }
    void callFnct(PyObject * fnct)
    {
        bp::call<void>(fnct);
        bp::call<void>(fnct);
    }
};

bp::class_<MyClass, boost::noncopyable> plugin("Plugin", bp::no_init);
plugin.def("callFnct", &MyClass::callFnct);

std::unique_ptr<MyClass> cls(new MyClass());

bp::object main_module = bp::import("__main__");
bp::object main_namespace = main_module.attr("__dict__");
bp::dict locals;
locals["plugin"] = bp::object(bp::ptr(cls.get()));

std::string scriptSource = 
                       "a=5\n"
                       "def my_func():\n"
                       "    a+=1\n"
                       "    plugin.log('won't work %d' % a)\n"
                       "plugin.log('this works')\n"
                       "plugin.callFnct(my_func)";
bp::object obj = bp::exec(bp::str(scriptSource), main_namespace, locals);

The initial call to plugin.log() works but once we call the python function in callFnct(), the namespace is gone so it can't see the variable a or the plugin module.

Does anyone know how to do bp::call<void>(fnct) by preserving the namespace and keep the variable a in scope?

1 Answer 1

4

That is because variables in non-local scopes cannot be rebound. It won't work even without calling to C++:

a = 5
def my_func():
    a += 5
    print(a)
my_func()

UnboundLocalError: local variable 'a' referenced before assignment

You need to import it first:

a = 5
def my_func():
    global a
    a += 5
    print(a)
my_func()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.