Stefan Seefeld wrote: > Neal, > > I should have read your mail more carefully before replying. Sorry for > that. > > > On 03/04/2010 01:35 PM, Neal Becker wrote: >> Stefan Seefeld wrote: >> >> >>> On 03/04/2010 11:59 AM, Neal Becker wrote: >>> >>>> int main () { >>>> Py_Initialize(); >>>> >>>> object main_module = import("__main__"); >>>> object main_namespace = main_module.attr("__dict__"); >>>> >>>> try { >>>> object result = exec ("import sys\n" >>>> "sys.path.append('./')\n" >>>> "import test_embed\n" >>>> "test_embed.five_square()\n", >>>> main_namespace); >>>> int five_squared = extract<int> (result); >>>> std::cout<< five_squared<< '\n'; >>>> } >>>> catch (error_already_set const&) { >>>> PyErr_Print(); >>>> } >>>> } >>>> >>>> >>>> test_embed.py: >>>> -------------------- >>>> def five_square (): >>>> return 5 ** 2 >>>> >>>> I get: >>>> ./test_embed >>>> TypeError: No registered converter was able to produce a C++ rvalue of >>>> type int from this Python object of type NoneType >>>> > > The problem is that you shouldn't attempt to extract anything from the > return value of an exec() call. It will contain None if everything goes > well. If not, the C API returns a null-pointer, which boost.python > translates into an err_already_set exception. > > I'm not exactly sure what you attempt to do. If you really want to > evaluate an expression (inclusively a function call), you should use > eval(), instead of exec(). > > The typical usage of exec() will be to run some code, then inspect the > global namespace to inspect any "side-effects" of this execution. > Notably, you may have your Python module store objects in the namespace, > and then let your C++ code extract and use them. > For example > > std::string code = > "import test_embed\n" > "result = test_embed.five_square()"; > > object = exec(code, global, global); > int result = extract<int>(global["result"]); > > Hope this helps, > Stefan >
OK. I had assumed, since it returned an object, that I could call a function and get back the python result. I didn't use eval, because eval is restricted to 1 expression, and so couldn't do something like: ''' sys.path.append('./') import module module.F (3)''' which is what I was trying to do _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig