/plearn/python/test/test_trampoline.cc

https://github.com/lisa-lab/PLearn · C++ · 89 lines · 50 code · 21 blank · 18 comment · 0 complexity · 74d6d5286f7f802bf4f28e09597c9b9c MD5 · raw file

  1. // Ensure that the Python function PyCFunction_NewEx works correctly
  2. #include <plearn/python/PythonCodeSnippet.h>
  3. #include <boost/function.hpp>
  4. #include <boost/bind.hpp>
  5. #include <iostream>
  6. using namespace PLearn;
  7. using namespace std;
  8. string python_code =
  9. "import sys\n"
  10. "\n"
  11. "def trampoline_call(x):\n"
  12. " y = injected_c_function(x)\n"
  13. " print >>sys.stderr, 'The C function returned the charming value',y\n"
  14. ;
  15. struct X
  16. {
  17. X(int value) : i(value) { }
  18. int i;
  19. void f();
  20. };
  21. void X::f()
  22. {
  23. cout << "X::f() called with i=" << i << endl;
  24. }
  25. typedef boost::function<void ()> XFunction;
  26. PyObject* python_trampoline(PyObject* self, PyObject* args)
  27. {
  28. XFunction *xfunc = reinterpret_cast<XFunction*>(self);
  29. // Should parse args here
  30. (*xfunc)();
  31. return PyInt_FromLong(64);
  32. }
  33. int main()
  34. {
  35. PP<PythonCodeSnippet> python = new PythonCodeSnippet(python_code);
  36. python->build();
  37. // Build my interesting instance of X
  38. X x(42);
  39. // Bind it to a function object
  40. XFunction xfunc = boost::bind(&X::f, x);
  41. // Create a Python Function Object
  42. PyMethodDef py_method;
  43. py_method.ml_name = NULL;
  44. py_method.ml_meth = python_trampoline;
  45. py_method.ml_flags = METH_VARARGS;
  46. py_method.ml_doc = NULL;
  47. PyObject* py_funcobj = PyCFunction_NewEx(&py_method,
  48. reinterpret_cast<PyObject*>(&xfunc),
  49. NULL /* module */);
  50. // Inject into the running python snippet
  51. python->setGlobalObject("injected_c_function", py_funcobj);
  52. // And now call our darling
  53. python->invoke("trampoline_call", 64);
  54. Py_XDECREF(py_funcobj);
  55. return 0;
  56. }
  57. /*
  58. Local Variables:
  59. mode:c++
  60. c-basic-offset:4
  61. c-file-style:"stroustrup"
  62. c-file-offsets:((innamespace . 0)(inline-open . 0))
  63. indent-tabs-mode:nil
  64. fill-column:79
  65. End:
  66. */
  67. // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :