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

--

      ...ich hab' noch einen Koffer in Berlin...

_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to