On 10.08.2025 21:22, tango foxtrot wrote:

It's my understanding that the oorexx  C++ api can be used to implement callbacks (where the SAA interface did not).  Is this true?  If so, can anyone point me to some samples?

Yes! You may want to consult the ooRexx book rexxapi.pdf.

This is what you need to do on the C++ side:

 * create a Rexx interpreter instance and do with it whatever you need to do! :)

Here excerpts from BSF4ooRexx from a function that gets invoked from Java via C++, the function takes some Rexx code ("jrexxcode") and an optional, single string argument ("jrexxArgument"). It then creates a Rexx interpreter instance (there may be any number of Rexx instances in a process), creates a Rexx routine object and then invokes it supplying the jrexxArgument, if any, fetches the result and returns it to Java:

   //
   
----------------------------------------------------------------------------------------------
   /* --rgf, 2022-08-06: allow for running simple Rexx scripts from Java using 
a separate RII, *
   optionally with a single string argument; will return the result as * a 
string only; if a Rexx
   Condition got raised the Rexx like error * string gets returned, led-in by
   "BSF4ooRexx/jniExecuteSimpleProcedureOnOwnRII()" * * * * Class:
   org_rexxla_bsf_engines_rexx_RexxAndJava * Method: 
jniExecuteSimpleProcedureOnOwnRII * Signature:
   (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT 
jstring JNICALL
   
Java_org_rexxla_bsf_engines_rexx_RexxAndJava_jniExecuteSimpleProcedureOnOwnRII 
(JNIEnv *env,
   jclass clzRAJ, jstring jrexxCode, jstring jrexxArgument) { jstring jres = 
NULL; { *RexxInstance
   *instance; RexxThreadContext *rtc; int bSuccess=RexxCreateInterpreter(&instance, 
&rtc, NULL);*
   if (bSuccess) { if (jrexxCode!=NULL) { char *rexxCode=(char *) 
JNU_GetStringNativeChars(env,
   jrexxCode); // convert to native string *RexxRoutineObject rro =
   rtc->NewRoutine("BSF4ooRexx850.jniExecuteSimpleProcedureOnOwnRII", rexxCode, 
strlen(rexxCode));
   * if (*rtc->CheckCondition()*) // a Rexx condition raised? { 
RexxDirectoryObject
   condObj=rtc->GetConditionInfo(); char * msg=RgfCreateRexxlikeErrorInfo (rtc, 
condObj,
   "/jniExecuteSimpleProcedureOnOwnRII().NewRoutine(), error 1"); jres = 
env->NewStringUTF( msg ) ;
   rtc->ClearCondition(); instance->Terminate(); free(msg); free(rexxCode); 
return jres; }
   free(rexxCode); // invoke routine // rexxArgument *RexxArrayObject 
arrArg=rtc->NewArray(0);* if
   (jrexxArgument!=NULL) { char *rexxArgument=(char *) 
JNU_GetStringNativeChars(env,
   jrexxArgument); // convert to native string rtc->ArrayAppend(arrArg,
   rtc->CString(rexxArgument)); free(rexxArgument); } *RexxObjectPtr
   result_obj=rtc->CallRoutine(rro, arrArg); **// call the routine* if 
(*rtc->CheckCondition()*) //
   a Rexx condition raised? { RexxDirectoryObject 
condObj=rtc->GetConditionInfo(); char *
   msg=RgfCreateRexxlikeErrorInfo (rtc, condObj,
   "/jniExecuteSimpleProcedureOnOwnRII().CallRoutine(), error 2"); jres = 
env->NewStringUTF( msg )
   ; rtc->ClearCondition(); instance->Terminate(); free(msg); return jres; } if 
(result_obj !=
   NULL) { jres = env->NewStringUTF( rtc->CString(result_obj) ) ; } } 
instance->Terminate(); } }
   return jres; }

Note: in this case an interpreter instance gets created (which is attached to the thread) and directly used for creating a routine and running (calling) it, terminating the instance.

You could cache the interpreter instance and use it later in your C++ program. You would use the interpreter instance to carry out an AttachThread(), interact with ooRexx, and if done do a DetachThread().

HTH

---rony



_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to