PLearn 0.1
|
00001 // Ensure that the Python function PyCFunction_NewEx works correctly 00002 00003 #include <plearn/python/PythonCodeSnippet.h> 00004 #include <boost/function.hpp> 00005 #include <boost/bind.hpp> 00006 #include <iostream> 00007 00008 using namespace PLearn; 00009 using namespace std; 00010 00011 string python_code = 00012 "import sys\n" 00013 "\n" 00014 "def trampoline_call(x):\n" 00015 " y = injected_c_function(x)\n" 00016 " print >>sys.stderr, 'The C function returned the charming value',y\n" 00017 ; 00018 00019 struct X 00020 { 00021 X(int value) : i(value) { } 00022 00023 int i; 00024 void f(); 00025 }; 00026 00027 void X::f() 00028 { 00029 cout << "X::f() called with i=" << i << endl; 00030 } 00031 00032 typedef boost::function<void ()> XFunction; 00033 00034 PyObject* python_trampoline(PyObject* self, PyObject* args) 00035 { 00036 XFunction *xfunc = reinterpret_cast<XFunction*>(self); 00037 00038 // Should parse args here 00039 00040 (*xfunc)(); 00041 00042 return PyInt_FromLong(64); 00043 } 00044 00045 int main() 00046 { 00047 PP<PythonCodeSnippet> python = new PythonCodeSnippet(python_code); 00048 python->build(); 00049 00050 // Build my interesting instance of X 00051 X x(42); 00052 00053 // Bind it to a function object 00054 XFunction xfunc = boost::bind(&X::f, x); 00055 00056 // Create a Python Function Object 00057 PyMethodDef py_method; 00058 py_method.ml_name = NULL; 00059 py_method.ml_meth = python_trampoline; 00060 py_method.ml_flags = METH_VARARGS; 00061 py_method.ml_doc = NULL; 00062 PyObject* py_funcobj = PyCFunction_NewEx(&py_method, 00063 reinterpret_cast<PyObject*>(&xfunc), 00064 NULL /* module */); 00065 00066 // Inject into the running python snippet 00067 python->setGlobalObject("injected_c_function", py_funcobj); 00068 00069 // And now call our darling 00070 python->invoke("trampoline_call", 64); 00071 00072 Py_XDECREF(py_funcobj); 00073 return 0; 00074 } 00075 00076 00077 00078 /* 00079 Local Variables: 00080 mode:c++ 00081 c-basic-offset:4 00082 c-file-style:"stroustrup" 00083 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00084 indent-tabs-mode:nil 00085 fill-column:79 00086 End: 00087 */ 00088 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 : 00089