使用命名空间从C++调用Python函数

3

我正在尝试从C++执行Python代码,该代码将定义一个Python函数并将其传回到C++,以便可以从那里调用它。这很好地实现了,但问题是我无法为Python函数提供其原始定义时的名称空间。

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);

对于 plugin.log() 的初始调用有效,但是一旦我们在 callFnct() 中调用Python函数,命名空间就消失了,因此它无法看到变量 aplugin 模块。

有人知道如何通过保留命名空间并保持变量 a 在范围内来执行 bp::call<void>(fnct) 吗?

1个回答

4

这是因为非局部作用域中的变量无法重新绑定。即使没有调用C++,它也无法工作:

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

UnboundLocalError: local variable 'a' referenced before assignment

您需要先导入它:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接