2015-02-06 28 views
3

我試圖從C++執行Python代碼,它將定義一個Python函數並將其傳回給C++,因此可以從那裏調用它。這工作正常,但問題是我不能提供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()作品最初的呼叫,但一旦我們調用了Python功能callFnct(),命名空間沒有了,因此它不能看到變量aplugin模塊。

有沒有人知道如何做bp::call<void>(fnct)保留名稱空間並保持變量a在範圍內?

回答

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() 
相關問題