Presentation is loading. Please wait.

Presentation is loading. Please wait.

T. Meyer ROD Software Workshop 18-19 July 2002 Scripting and Interpreted Languages Tom Meyer Iowa State University

Similar presentations


Presentation on theme: "T. Meyer ROD Software Workshop 18-19 July 2002 Scripting and Interpreted Languages Tom Meyer Iowa State University"— Presentation transcript:

1 T. Meyer Meyer@iastate.edu ROD Software Workshop 18-19 July 2002 Scripting and Interpreted Languages Tom Meyer Iowa State University Meyer@iastate.edu

2 T. Meyer Meyer@iastate.edu ROD Software Workshop 18-19 July 2002 Where to Use  Use for middle layer(s), where easy and rapid reconfiguration is necessary.  I don’t think we need to look further than CINT or Python for an interpreted language.

3 T. Meyer Meyer@iastate.edu ROD Software Workshop 18-19 July 2002 A Test Case  On a Friday morning, I asked an undergraduate student to code a test case of a layer of Python code sandwiched between two layers of C++ code.  By that evening, he had a working example.  By the next day, he had a demo version interfaced to RodModule. His demo prompts the user for ROD parameters and a data string to be passed to the ECHO primitive.  The hardest part was understanding the poorly written documentation.  However, he is a VERY capable student with a lot of Python experience.  Nevertheless, this convinced me that this approach is very feasible.  I’m pretty sure CINT would be comparably easy to interface, but no test case has been done (volunteers?).

4 T. Meyer Meyer@iastate.edu ROD Software Workshop 18-19 July 2002 py_demo: Source Files  py_demo.cxx - The main routine  ParamGetter.h - C++ header file for ParamGetter class  ParamGetter.cxx – The implementation of ParamGetter class  py_demo.py – The Python source

5 T. Meyer Meyer@iastate.edu ROD Software Workshop 18-19 July 2002 py_demo.cxx (1) // py_demo.cxx // This demo calls a python script from C++ #include "py_demo/ParamGetter.h" // My code to deal with returned params #include #include "RodPrimitive.h" #include "primParams.h" #include "RodModule.h" #include "../VmeInterface/RCCVmeInterface.h" using namespace SctPixelRod; int main(int argc, char **argv) { RCCVmeInterface *vme = new RCCVmeInterface(); // Initialize my ParamGetter class. See the code in the py_demo directory. // What this does is execute the function GetParams from the python script // echo_params.py. We can then use p's methods to get the returned params. ParamGetter p("echo_params", argc, argv); // Get five long ints from the dictionary returned by GetParams, and // deal with them appropriately. UINT32 baseaddr = p.GetLongParam("BaseAddress"); UINT32 mapsize = p.GetLongParam("MapSize"); UINT32 slot = p.GetLongParam("SlotNum"); UINT32 numslaves = p.GetLongParam("NumSlaves"); UINT32 body = p.GetLongParam("ByteToEcho"); RodModule *rod = new RodModule(baseaddr, mapsize, *vme, slot, numslaves); // Create a RodPrimitive based on the parameters we got. RodPrimitive *rp = new RodPrimitive(4,1,ECHO,&body);

6 T. Meyer Meyer@iastate.edu ROD Software Workshop 18-19 July 2002 py_demo.cxx (2) // Create a RodPrimList with rp as its only element. RodPrimList *pl = new RodPrimList(1); pl->insert(pl->begin(), *rp); // Build PrimList message. pl->bufferBuild(); // Now send it. rod->sendPrimList(MASTER_INBUFF, *pl); // Wait for the PrimList to finish executing. while (rod->primHandler != PRIM_EXECUTING && rod->primHandler != PRIM_WAITING) {} // Deal with the output from the Rod. RodOutList *outlist = rod->getOutList(); cout << "outLength=" << outList[0] << ", outIndex=" << outList[1] << ", outNumPrims=" << outList[2] << endl << "primLength=" << outList[3] << ", primIndex=" << outList[4] << ", primId=" << outList[5] << endl; cout << "data: " << endl; for (int i=0; i<outList[3]-3; i++) cout << outList[6+i] << endl; // Clear the PrimList and free the memory we used. primList->clear(); delete vme, rod, pl, rp, outlist; return 0; }

7 T. Meyer Meyer@iastate.edu ROD Software Workshop 18-19 July 2002 py_demo.py (1) class App: # App constructor def __init__(self, master): from Tkinter import * # Create some string variables to hold the input parameters. self.base=StringVar(master) self.byte=StringVar(master) self.maps=StringVar(master) self.slot=StringVar(master) self.slvs=StringVar(master) # Create a tk frame that will hold each element of our gui. self.frame = Frame(master) self.frame.pack() # Now create a subframe of frame that holds the entry box for # the base address parameter. self.subframe1 = Frame(self.frame) self.ent1 = Entry(self.subframe1, textvar=self.base) self.ent1.pack(side=RIGHT) self.lab1 = Label(self.subframe1, text='Base address:') self.lab1.pack(side=LEFT) self.subframe1.pack() # And again for the map size parameter. self.subframe2 = Frame(self.frame) self.ent2 = Entry(self.subframe2, textvar=self.maps) self.ent2.pack(side=RIGHT) self.lab2 = Label(self.subframe2, text='Map size:') self.lab2.pack(side=LEFT) self.subframe2.pack()

8 T. Meyer Meyer@iastate.edu ROD Software Workshop 18-19 July 2002 py_demo.py (2) # And again for the slot number. self.subframe3 = Frame(self.frame) self.ent3 = Entry(self.subframe3, textvar=self.slot) self.ent3.pack(side=RIGHT) self.lab3 = Label(self.subframe3, text='Slot number:') self.lab3.pack(side=LEFT) self.subframe3.pack() # Still another for the number of slaves. self.subframe4 = Frame(self.frame) self.ent4 = Entry(self.subframe4, textvar=self.slvs) self.ent4.pack(side=RIGHT) self.lab4 = Label(self.subframe4, text='Number of slaves:') self.lab4.pack(side=LEFT) self.subframe4.pack() # Yet another for the byte to actually echo. self.subframe5 = Frame(self.frame) self.ent5 = Entry(self.subframe5, textvar=self.byte) self.ent5.pack(side=RIGHT) self.lab5 = Label(self.subframe5, text='Byte to echo:') self.lab5.pack(side=LEFT) self.subframe5.pack() # At the bottom, put in a button to click when you're done # inputting stuff. When clicked, it will call the command # self.done(). self.donebutton=Button(self.frame,text="Done", command=self.done) self.donebutton.pack()

9 T. Meyer Meyer@iastate.edu ROD Software Workshop 18-19 July 2002 py_demo.py (3) # When the Done button is clicked, this function is called and # the frame is closed. def done(self): self.frame.quit() # After the frame has been closed, this function can be called to # get the values input by the user. It returns a dictionary. def get_vals(self): return { 'BaseAddress' : int(self.base.get()), 'MapSize' : int(self.maps.get()), 'SlotNum' : int(self.slot.get()), 'NumSlaves' : int(self.slvs.get()), 'ByteToEcho' : int(self.byte.get()) } # The function name "GetParams" is hard-wired into the ParamGetter # C++ class. This is the function that will be called when the class # is initialized. def GetParams(): import Tkinter # Create a root window for Tk. root = Tkinter.Tk() # Create an App within the Tk root window. app = App(root) # Give it a name. root.title("Echo parameters") # Start the Tk event loop. root.mainloop() # The user terminates the event loop by clicking the Done button. # Now return the dictionary to C++ to deal with as it pleases. return app.get_vals()

10 T. Meyer Meyer@iastate.edu ROD Software Workshop 18-19 July 2002 ParamGetter.h #ifndef PARAMGETTER_H #define PARAMGETTER_H #include #include // Standard Python include class ParamGetter { private: PyObject *pName, *pModule, *pDict, *pFunc; PyObject *pArgs, *pValue; void Crash(string message); public: ParamGetter(string module_name, int argc, char **argv); ~ParamGetter(); long GetLongParam(string param_name); // Get a long int from the dictionary returned by a // python script. string GetStringParam(string param_name); // Get a std::string from the dictionary returned by a // python script. }; #endif

11 T. Meyer Meyer@iastate.edu ROD Software Workshop 18-19 July 2002 ParamGetter.cxx (1) #include "ParamGetter.h" // Functions to get parameters returned in a dictionary from a python script void ParamGetter::Crash(string message) { // Exit neatly so that core isn't dumped. You always have to do a DECREF // because of the way Python handles memory. cerr << message << endl; PyErr_Print(); Py_XDECREF(pValue); // Free all the memory Py_XDECREF(pArgs); // that we did not Py_XDECREF(pModule); // "borrow" from Py_XDECREF(pName); // Python Py_Finalize(); } ParamGetter::ParamGetter(string module_name, int argc, char **argv) { Py_Initialize(); // Start the interpreter PySys_SetArgv(argc,argv); // Set the arguments correctly }

12 T. Meyer Meyer@iastate.edu ROD Software Workshop 18-19 July 2002 ParamGetter.cxx (2) pName = PyString_FromString(module_name.c_str()); pModule = PyImport_Import(pName); //Import the python module if (!pModule) { Crash("Unable to load module."); return; } pDict = PyModule_GetDict(pModule); // Get a dictionary containing all the objects in the module pFunc = PyDict_GetItemString(pDict, "GetParams"); // Grab a pointer to the function GetParams pArgs = PyTuple_New(0); // We don't need to pass it any arguments if (!pFunc) { Crash("Unable to load function."); return; } if (!PyCallable_Check(pFunc)) { Crash("Unable to call function."); return; } pValue = PyObject_CallObject(pFunc, pArgs); // Call the function! if (!pValue) { Crash("Call failed."); return; }


Download ppt "T. Meyer ROD Software Workshop 18-19 July 2002 Scripting and Interpreted Languages Tom Meyer Iowa State University"

Similar presentations


Ads by Google