]> SALOME platform Git repositories - modules/superv.git/blob - src/GraphExecutor/DataFlowExecutor_PyDynInvoke.cxx
Salome HOME
9df177be3ba08565dd7f8782f2e39309768ed3ab
[modules/superv.git] / src / GraphExecutor / DataFlowExecutor_PyDynInvoke.cxx
1 //  SUPERV GraphExecutor : contains classes that permit execution of graphs and particularly the execution automaton
2 //
3 //  Copyright (C) 2003  CEA/DEN, EDF R&D
4 //
5 //
6 //
7 //  File   : DataFlowExecutor_PyDynInvoke.cxx
8 //  Author : Jean Rahuel, CEA
9 //  Module : SUPERV
10 //  $Header:
11
12 using namespace std;
13
14 #include <stdarg.h>
15 #include <map>
16
17 #include "DataFlowExecutor_InNode.hxx"
18
19 using namespace CORBA ;
20
21 static PyObject * MyPyObjRef = NULL ;
22 static PyObject * MyPyObjIor = NULL ;
23 static PyObject * MyPyRunMethod = NULL ;
24
25 static PyMethodDef MethodPyRunMethod[] = {
26   { "RunMethod", PyRunMethod, METH_VARARGS },
27   { NULL,        NULL }
28 };
29
30 bool GraphExecutor::InNode::InitPython() {
31   cdebug_in << "InitPython" << endl ;
32
33 //  PyObject * Module = Py_InitModule( "InitPyRunMethod" , MethodPyRunMethod ) ;
34   Py_InitModule( "InitPyRunMethod" , MethodPyRunMethod ) ;
35 //  PyObject * Dictionnary = PyModule_GetDict( Module ) ;
36 //  InitPyDynInvokeError = PyErr_NewException( "InitPyDynInvokeError" , NULL , NULL ) ;
37 //  PyDict_SetItemString( Dictionnary , InitPyDynInvokeError ) ;
38   cdebug << ThreadNo() << "Py_Initialized() " << endl ;
39
40   string aPyFunc ;
41 //  aPyFunc = "print 'InitPyRunMethod'\n" ;
42   aPyFunc = "import InitPyRunMethod\n" ;
43 //  aPyFunc += "print 'sys'\n" ;
44   aPyFunc += "import sys\n" ;
45 //  aPyFunc += "print 'CORBA'\n" ;
46   aPyFunc += "import CORBA\n" ;
47 //  aPyFunc += "print 'omniORB'\n" ;
48   aPyFunc += "import omniORB\n" ;
49 //  aPyFunc += "print 'PyObjRef'\n" ;
50   aPyFunc += "def PyObjRef( IORObjStr ) :\n" ;
51 //  aPyFunc += "    print 'PyObjRef',IORObjStr\n" ;
52   aPyFunc += "    orb = CORBA.ORB_init( sys.argv , CORBA.ORB_ID )\n" ;
53 //  aPyFunc += "    print 'PyObjRef orb',orb\n" ;
54   aPyFunc += "    objref = orb.string_to_object( IORObjStr )\n" ;
55 //  aPyFunc += "    print 'PyObjRef IORObjStr objref',IORObjStr,objref\n" ;
56   aPyFunc += "    return objref\n" ;
57   aPyFunc += "InitPyRunMethod.RunMethod( PyObjRef )\n" ;
58   if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
59     cdebug << ThreadNo() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
60     return false ;
61   }
62   MyPyObjRef = MyPyRunMethod ;
63
64   aPyFunc = "import InitPyRunMethod\n" ;
65   aPyFunc += "import sys\n" ;
66   aPyFunc += "import CORBA\n" ;
67   aPyFunc += "import omniORB\n" ;
68   aPyFunc += "def PyObjIor( ObjRef ) :\n" ;
69 //  aPyFunc += "    print 'PyObjIor',ObjRef\n" ;
70   aPyFunc += "    orb = CORBA.ORB_init( sys.argv , CORBA.ORB_ID )\n" ;
71 //  aPyFunc += "    print 'PyObjIor orb',orb\n" ;
72   aPyFunc += "    objIor = orb.object_to_string( ObjRef )\n" ;
73 //  aPyFunc += "    print 'PyObjIor ObjRef objIor',ObjRef,objIor\n" ;
74   aPyFunc += "    return objIor\n" ;
75   aPyFunc += "InitPyRunMethod.RunMethod( PyObjIor )\n" ;
76   if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
77     cdebug << ThreadNo() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
78     return false ;
79   }
80   MyPyObjIor = MyPyRunMethod ;
81
82   cdebug_out << "InitPython" << endl ;
83   return true ;
84 }
85
86 PyObject * GraphExecutor::InNode::InitPyDynInvoke(
87                                   char * PyFuncName ,
88                                   const SUPERV::ListOfStrings * aPythonFunction ) {
89   bool RetVal = true ;
90   string aPyFunc ;
91
92   cdebug_in << "InitPyDynInvoke '" << PyFuncName << "' length "
93             << (*aPythonFunction).length() << endl ;
94
95   if ( (*aPythonFunction).length() ) {
96     unsigned int i ;
97     aPyFunc += "import InitPyRunMethod\n" ;
98     for ( i = 0 ; i < (*aPythonFunction).length() ; i++ ) {
99       aPyFunc += (*aPythonFunction)[ i ] ;
100       aPyFunc += "\n" ;
101     }
102     aPyFunc += "InitPyRunMethod.RunMethod( " ;
103     aPyFunc += PyFuncName ;
104     aPyFunc += " )\n" ;
105     cdebug << "InitPyDynInvoke PyRun_SimpleString " << endl << aPyFunc << endl ;
106     if ( PyRun_SimpleString( (char *) aPyFunc.c_str() ) ) {
107       cdebug << ThreadNo() << " PyRun_SimpleString ERROR " << endl << aPyFunc << endl ;
108       RetVal = false ;
109     }
110     else {
111       PyFuncRunned( true ) ;
112 //      _MyPyRunMethod = MyPyRunMethod ; // To mutex
113       cdebug << ThreadNo() << "PyRun_SimpleString( " << (*aPythonFunction)[ 0 ]
114              << " )" << endl ;
115     }
116     cdebug_out << "InitPyDynInvoke" << endl ;
117     if ( RetVal ) {
118       return MyPyRunMethod ;
119     }
120   }
121
122   return NULL ;
123 }
124
125 extern "C" PyObject * PyRunMethod( PyObject * dummy , PyObject * Args ) {
126 //  cout << "PyRunMethod -->" << endl ;
127   PyObject * Result = NULL ;
128   PyObject * Temp = NULL ;
129   if ( PyArg_ParseTuple( Args , "O:set_callback" , & Temp ) ) {
130 //    cout << "PyArg_ParsedTuple" << endl ;
131     if ( !PyCallable_Check( Temp ) ) {
132 //      PyErr_SetString( PyExc_TypeError , "PyRunMethod must be callable" ) ;
133 //      cout << "PyRunMethod must be callable" << endl ;
134       return NULL ;
135     }
136     Py_XINCREF( Temp ) ;
137     Py_XDECREF( MyPyRunMethod ) ;
138     MyPyRunMethod = Temp ;
139     Py_INCREF( Py_None ) ;
140     Result = Py_None ;
141   }
142 //  cout << "<-- PyRunMethod" << endl ;
143   return Result ;
144 }
145
146 bool GraphExecutor::InNode::PyDynInvoke( PyObject * MyPyRunMethod ,
147                                          const char *method , 
148                                          ServicesAnyData * inParams , int nInParams ,
149                                          ServicesAnyData * outParams , int nOutParams ) {
150   int i ;
151
152   bool RetVal = true ;
153
154   int n_in  = nInParams ;
155   int n_out = nOutParams ;
156   const char * sname;
157
158   cdebug_in << ThreadNo() << "GraphExecutor::InNode::PyDynInvoke " << method << " " << n_in
159             << " InArgs " << n_out << " OutArgs" << endl ;
160
161   CORBA::Any data ;
162
163   PyObject * ArgsList = NULL ;
164   PyObject * ArgValue = NULL ;
165   PyObject * Result = NULL ;
166   PyObject * MyPyObjRefList = NULL ;
167   PyObject * ResultObj = NULL ;
168   PyObject * MyPyObjIorList = NULL ;
169   PyObject * ResultIor = NULL ;
170
171   CORBA::Object_ptr ObjRef ;
172   char * IORObjRef ;
173
174   ArgsList = PyTuple_New( n_in ) ;
175
176   for ( i = 0 ; i < n_in ; i++ ) {
177     data = inParams[i].Value ;
178     sname = inParams[i].Name.c_str() ;
179     switch ( data.type()->kind() ) {
180     case CORBA::tk_string : {
181       char * t ;
182       data >>= t ;
183       ArgValue = Py_BuildValue( "s" , t ) ;
184       PyTuple_SetItem( ArgsList , i , ArgValue ) ;
185       cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << t << " (string) "
186              << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
187              << ArgValue->ob_refcnt << endl ;
188       break ;
189     }
190     case CORBA::tk_boolean : {
191       bool b ;
192       data >>= (CORBA::Any::to_boolean ) b ;
193       ArgValue = Py_BuildValue( "b" , b ) ;
194       PyTuple_SetItem( ArgsList , i , ArgValue ) ;
195       cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << b
196              << " (boolean) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
197              << ArgValue->ob_refcnt << endl ;
198       break ;
199     }
200     case CORBA::tk_char : {
201       unsigned char c ;
202       data >>= (CORBA::Any::to_char ) c ;
203       ArgValue = Py_BuildValue( "c" , c ) ;
204       PyTuple_SetItem( ArgsList , i , ArgValue ) ;
205       cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << c
206              << " (char) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
207              << ArgValue->ob_refcnt << endl ;
208       break ;
209     }
210     case CORBA::tk_short : {
211       short s ;
212       data >>= s ;
213       ArgValue = Py_BuildValue( "h" , s ) ;
214       PyTuple_SetItem( ArgsList , i , ArgValue ) ;
215       cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << s
216              << " (short) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
217              << ArgValue->ob_refcnt << endl ;
218       break ;
219     }
220     case CORBA::tk_long : {
221       long l ;
222       data >>= l ;
223       ArgValue = Py_BuildValue( "l" , l ) ;
224       PyTuple_SetItem( ArgsList , i , ArgValue ) ;
225       cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << l
226              << " (long) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
227              << ArgValue->ob_refcnt << endl ;
228       break ;
229     }
230     case CORBA::tk_float : {
231       float f ;
232       data >>= f ;
233       ArgValue = Py_BuildValue( "f" , f ) ;
234       PyTuple_SetItem( ArgsList , i , ArgValue ) ;
235       cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << f
236              << " (float) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
237              << ArgValue->ob_refcnt << endl ;
238       break ;
239     }
240     case CORBA::tk_double : {
241       double d ;
242       data >>= d ;
243       ArgValue = Py_BuildValue( "d" , d ) ;
244       PyTuple_SetItem( ArgsList , i , ArgValue ) ;
245       cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value " << d
246              << " (double) ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
247              << ArgValue->ob_refcnt << endl ;
248       break ;
249     }
250     case CORBA::tk_objref : {
251       MyPyObjRefList = PyTuple_New( 1 ) ;
252       PyObject * ObjValue ;
253       data >>= ObjRef ;
254       IORObjRef = ObjectToString( ObjRef ) ;
255       ObjValue = Py_BuildValue( "s" , IORObjRef ) ;
256       PyTuple_SetItem( MyPyObjRefList , 0 , ObjValue ) ;
257       cdebug << "ArgIn" << i << " : " << sname << " " << method << " " << " Value " << IORObjRef << " (objref) "
258              << MyPyObjRef->ob_refcnt << "/" << MyPyObjRefList->ob_refcnt << endl ;
259       ResultObj = PyEval_CallObject( MyPyObjRef , MyPyObjRefList ) ;
260       cdebug << "ObjValue->ob_refcnt" << ObjValue->ob_refcnt << endl ;
261       ArgValue = Py_BuildValue( "O" , ResultObj ) ;
262       PyTuple_SetItem( ArgsList , i , ArgValue ) ;
263       cdebug << "ArgIn" << i << " : " << sname << " " << method << " Value  (objref) ArgsList->ob_refcnt"
264              << ArgsList->ob_refcnt << " ArgValue->ob_refcnt" << ArgValue->ob_refcnt << endl ;
265       cdebug << "MyPyObjRefList->ob_refcnt " << MyPyObjRefList->ob_refcnt-1 << endl ;
266       Py_DECREF( MyPyObjRefList ) ;
267       if ( CORBA::is_nil( ObjRef ) ) {
268         ResultObj = NULL ;
269       }
270       else {
271         cdebug << "ResultObj->ob_refcnt " << ResultObj->ob_refcnt-1 << endl ;
272         Py_DECREF( ResultObj ) ;
273       }
274       break ;
275     }
276     default : {
277       cdebug << "ArgIn" << i << " : " << sname << " Value " << "(other ERROR)" << endl ;
278     }
279     }
280   }
281
282   if (!PyCallable_Check( MyPyRunMethod )) {
283     RetVal = false;
284     return RetVal;
285   }
286   else {
287     Result = PyEval_CallObject( MyPyRunMethod , ArgsList ) ;
288     cdebug << "ArgsList->ob_refcnt" << ArgsList->ob_refcnt << endl ;
289     
290     if ( Result == NULL ) {
291       cdebug_out << "GraphExecutor::InNode::PyDynInvoke " << method << " Error Result == NULL" << endl ;
292       RetVal = false ;
293     }
294     else {
295       for ( i = 0 ; i < n_out ; i++ ) {
296         data = outParams[i].Value ;
297         sname = outParams[i].Name.c_str() ;
298         switch ( data.type()->kind() ) {
299         case CORBA::tk_string : {
300           char * t = "" ;
301           if ( PyTuple_Check( Result ) ) {
302             ArgValue = PyTuple_GetItem( Result , i ) ;
303           }
304           else {
305             ArgValue = Result ;
306           }
307           if ( !PyString_Check( ArgValue ) ) {
308             cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (string)" << endl ;
309           }
310           else {
311             t = PyString_AsString( ArgValue ) ;
312           }
313           data <<= t ;
314           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << t << " (string)"
315             << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
316             << ArgValue->ob_refcnt << endl ;
317           break ;
318         }
319         case CORBA::tk_boolean : {
320           bool b = false ;
321           if ( PyTuple_Check( Result ) ) {
322             ArgValue = PyTuple_GetItem( Result , i ) ;
323           }
324           else {
325             ArgValue = Result ;
326           }
327           if ( !PyInt_Check( ArgValue ) ) {
328             cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (boolean)" << endl ;
329           }
330           else {
331             b = PyInt_AsLong( ArgValue ) ;
332           }
333           data <<= (CORBA::Any::from_boolean ) b ;
334           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << b << " (boolean)"
335             << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
336             << ArgValue->ob_refcnt << endl ;
337           break ;
338         }
339         case CORBA::tk_char : {
340           unsigned char c = 0 ;
341           if ( PyTuple_Check( Result ) ) {
342             ArgValue = PyTuple_GetItem( Result , i ) ;
343           }
344           else {
345             ArgValue = Result ;
346           }
347           if ( !PyInt_Check( ArgValue ) ) {
348             cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (char)" << endl ;
349           }
350           else {
351             c = PyInt_AsLong( ArgValue ) ;
352           }
353           data <<= (CORBA::Any::from_char ) c ;
354           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << c << " (char)"
355             << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
356             << ArgValue->ob_refcnt << endl ;
357           break ;
358         }
359         case CORBA::tk_short : {
360           short s = 0 ;
361           if ( PyTuple_Check( Result ) ) {
362             ArgValue = PyTuple_GetItem( Result , i ) ;
363           }
364           else {
365             ArgValue = Result ;
366           }
367           if ( !PyInt_Check( ArgValue ) ) {
368             cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (short)" << endl ;
369           }
370           else {
371             s = PyInt_AsLong( ArgValue ) ;
372           }
373           data <<= s ;
374           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << s << " (short)"
375             << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
376             << ArgValue->ob_refcnt << endl ;
377           break ;
378         }
379         case CORBA::tk_long : {
380           long l = 0 ;
381           if ( PyTuple_Check( Result ) ) {
382             ArgValue = PyTuple_GetItem( Result , i ) ;
383           }
384           else {
385             ArgValue = Result ;
386           }
387           if ( PyLong_Check( ArgValue ) ) {
388             l = PyLong_AsLong( ArgValue ) ;
389           }
390           else if ( PyInt_Check( ArgValue ) ) {
391             l = PyInt_AsLong( ArgValue ) ;
392           }
393           else {
394             cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (CORBA::tk_long)" << endl ;
395           }
396           data <<= l ;
397           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << l << " (long)"
398             << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
399               << ArgValue->ob_refcnt << endl ;
400           break ;
401         }
402         case CORBA::tk_float : {
403           float f = 0 ;
404           if ( PyTuple_Check( Result ) ) {
405             ArgValue = PyTuple_GetItem( Result , i ) ;
406           }
407           else {
408             ArgValue = Result ;
409           }
410           if ( !PyFloat_Check( ArgValue ) ) {
411             cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (float)" << endl ;
412           }
413           else {
414             f = PyFloat_AsDouble( ArgValue ) ;
415           }
416           data <<= f ;
417           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << f << " (float)"
418             << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
419             << ArgValue->ob_refcnt << endl ;
420           break ;
421         }
422         case CORBA::tk_double : {
423           double d = 0 ;
424           if ( PyTuple_Check( Result ) ) {
425             ArgValue = PyTuple_GetItem( Result , i ) ;
426           }
427           else {
428             ArgValue = Result ;
429           }
430           if ( !PyFloat_Check( ArgValue ) ) {
431             cdebug << "ArgOut" << i << " : " << sname << " " << method << " ERROR (double)" << endl ;
432           }
433           else {
434             d = PyFloat_AsDouble( ArgValue ) ;
435           }
436           data <<= d ;
437           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << d << " (double)"
438             << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ArgValue->ob_refcnt"
439             << ArgValue->ob_refcnt << endl ;
440           break ;
441         }
442         case CORBA::tk_objref : {
443           PyObject * ObjIor ;
444           MyPyObjIorList = PyTuple_New( 1 ) ;
445           if ( PyTuple_Check( Result ) ) {
446             ObjIor = PyTuple_GetItem( Result , i ) ;
447           }
448           else {
449             ObjIor = Result ;
450           }
451           cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << "(object reference) "
452             << " ArgsList->ob_refcnt" << ArgsList->ob_refcnt << " ObjIor->ob_refcnt"
453             << ObjIor->ob_refcnt << endl ;
454           Py_INCREF( ObjIor ) ;
455 //        PyObject_Print( ObjIor , stdout , 0 ) ;
456           PyTuple_SetItem( MyPyObjIorList , 0 , ObjIor ) ;
457           ResultIor = PyEval_CallObject( MyPyObjIor , MyPyObjIorList ) ;
458           cdebug << "ObjIor->ob_refcnt " << ObjIor->ob_refcnt-1 << endl ;
459           Py_DECREF( ObjIor ) ;
460           cdebug << "MyPyObjIorList->ob_refcnt " << MyPyObjIorList->ob_refcnt-1 << endl ;
461           Py_DECREF( MyPyObjIorList ) ;
462           cdebug << "MyPyObjIor->ob_refcnt " << MyPyObjIor->ob_refcnt << endl ;
463           if ( ResultIor ) {
464             char * IOR = NULL ;
465             IOR = PyString_AsString( ResultIor ) ;
466             ObjRef = StringToObject( IOR ) ;
467             data <<= ObjRef ;
468             IORObjRef = ObjectToString( ObjRef ) ;
469             cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << IORObjRef << " (objref) "
470               << endl ;
471             if ( CORBA::is_nil( ObjRef ) ) {
472               ResultIor = NULL ;
473             }
474             else {
475               cdebug << "ResultIor->ob_refcnt " << ResultIor->ob_refcnt-1 << endl ;
476               Py_DECREF( ResultIor ) ;
477             }
478           }
479           else {
480             cdebug_out << "GraphExecutor::InNode::PyDynInvoke Error ResultIor == NULL"
481               << method << " " << endl ;
482             RetVal = false ;
483           }
484           break ;
485         }
486           default : {
487             cdebug << "ArgOut" << i << " : " << sname << " " << method << " Value " << "(other ERROR)" << endl ;
488           }
489         }
490         outParams[i].Value = data ;
491       }
492       
493       cdebug << "Result->ob_refcnt" << Result->ob_refcnt-1 << endl ;
494       Py_DECREF( Result ) ;
495     }
496     
497     cdebug << "GraphExecutor::InNode::PyDynInvoke ArgsList->ob_refcnt"
498       << ArgsList->ob_refcnt-1 << endl ;
499     Py_DECREF( ArgsList ) ;
500     
501     cdebug_out << "GraphExecutor::InNode::PyDynInvoke " << method << endl ;
502     
503     return RetVal ;
504   }
505
506 }