From: Rony G. F. <Ron...@wu...> - 2009-04-25 12:16:31
|
Hi, a few little questions, before being able to go further at the moment: 1. How would one be able to define some RexxPackageLoader function named "testLoader" in C++ code such that it can be used in the RexxPackageEntry field "loader"? (Would just need the correct function header and the first statement in the body for accessing the context object!) * Would this loader (and the matching unloader) be called once for each RexxInstance that loads/requires the library or would it be called once for all the RexxInstances in a process? 2. The function RexxGetPackage() loads the library indicated in the OOREXX_GET_PACKAGE(package) stub. If a library got loaded as part of the new RexxCreateInterpreter using the option LOAD_REQUIRED_LIBRARY or via the loadLibrary()-API, then does RexxGetPackage() get executed as well? * If so, how could one load a different set of functions/routines that are defined in a different package library in the same dll/so and causing the RexxGetPackage() to *not* be executed anymore, if a Rexx program requires that very same dll/so later on? [Use case: if the Rexx interpreter gets invoked via Java, then the external functions to load or unload Java itself must not be made available. Hence one would need to create another package with the desired external functions, but how would one load that package then, as currently it seems that one needs to use the name of the dll/so library?] 3. Are all loaded native routines (via requires-library or the loadLibrary-API) available to all programs running under a certain RexxInstance or visible among all RexxInstances in a process? TIA, ---rony |
From: Rick M. <obj...@gm...> - 2009-04-25 12:34:06
|
On Sat, Apr 25, 2009 at 8:15 AM, Rony G. Flatscher <Ron...@wu...> wrote: > Hi, > > a few little questions, before being able to go further at the moment: > > How would one be able to define some RexxPackageLoader function named > "testLoader" in C++ code such that it can be used in the RexxPackageEntry > field "loader"? > (Would just need the correct function header and the first statement in the > body for accessing the context object!) The oorexxapi.h header defines the type signatures of the loader and unloader function. The signatures typedef void (RexxEntry *RexxPackageLoader)(RexxThreadContext *); typedef void (RexxEntry *RexxPackageUnloader)(RexxThreadContext *); The RexxThreadContext instance is for the instance that initiated the load operations. The load is performed on a process basis, so you'll only see one of these. And, like all thread context calls, any objects references you cache in your C++ needs to be globally protected by using RequestGlobalReference() (and released using ReleaseGlobalReference() in the unloader). > > Would this loader (and the matching unloader) be called once for each > RexxInstance that loads/requires the library or would it be called once for > all the RexxInstances in a process? > Only once per process. > The function RexxGetPackage() loads the library indicated in the > OOREXX_GET_PACKAGE(package) stub. If a library got loaded as part of the new > RexxCreateInterpreter using the option LOAD_REQUIRED_LIBRARY or via the > loadLibrary()-API, then does RexxGetPackage() get executed as well? It's all the same mechanism. > > If so, how could one load a different set of functions/routines that are > defined in a different package library in the same dll/so and causing the > RexxGetPackage() to *not* be executed anymore, if a Rexx program requires > that very same dll/so later on? Huh? A package is a self-contained entitiy, and it defines just one set of information. If you wish to have other packages sharing code, then create a small DLL that only defines the package functions you require but link to the larger body of code for the actual implementation. > [Use case: if the Rexx interpreter gets invoked via Java, then the external > functions to load or unload Java itself must not be made available. Hence > one would need to create another package with the desired external > functions, but how would one load that package then, as currently it seems > that one needs to use the name of the dll/so library?] Use multiple packages, like I indicated. > > Are all loaded native routines (via requires-library or the loadLibrary-API) > available to all programs running under a certain RexxInstance or visible > among all RexxInstances in a process? They are all visibile globally. > > TIA, > > ---rony > > > > ------------------------------------------------------------------------------ > Crystal Reports - New Free Runtime and 30 Day Trial > Check out the new simplified licensign option that enables unlimited > royalty-free distribution of the report engine for externally facing > server and web deployment. > http://p.sf.net/sfu/businessobjects > _______________________________________________ > Oorexx-devel mailing list > Oor...@li... > https://lists.sourceforge.net/lists/listinfo/oorexx-devel > > |
From: Rony G. F. <Ron...@wu...> - 2009-04-25 14:05:59
|
Rick McGuire wrote: > On Sat, Apr 25, 2009 at 8:15 AM, Rony G. Flatscher > <Ron...@wu...> wrote: > >> Hi, >> >> a few little questions, before being able to go further at the moment: >> >> How would one be able to define some RexxPackageLoader function named >> "testLoader" in C++ code such that it can be used in the RexxPackageEntry >> field "loader"? >> (Would just need the correct function header and the first statement in the >> body for accessing the context object!) >> > > The oorexxapi.h header defines the type signatures of the loader and > unloader function. The signatures > > typedef void (RexxEntry *RexxPackageLoader)(RexxThreadContext *); > typedef void (RexxEntry *RexxPackageUnloader)(RexxThreadContext *); > Thanks, this allowed me to define: // typedef void (RexxEntry *RexxPackageLoader)(RexxThreadContext *); void RexxEntry testLoader (RexxThreadContext *rtc) { fprintf(stderr, "in testLoader() ...\n"); fprintf(stderr, "in testLoader() rtc=[%p]...\n", rtc); fprintf(stderr, "in testLoader() .Nil=[%s]...\n", rtc->ObjectToStringValue(rtc->Nil())); fflush(stderr); } // typedef void (RexxEntry *RexxPackageUnloader)(RexxThreadContext *); void RexxEntry testUnloader (RexxThreadContext * rtc) { fprintf(stderr, "in testUnloader() ...\n"); fflush(stderr); } Using them later as: RexxPackageEntry testLib2_package_entry = { STANDARD_PACKAGE_HEADER REXX_INTERPRETER_4_0_0, // anything after 4.0.0 will work "testLib-AnyName", // name of the package "0.0", // package information testLoader, // load function testUnloader, // unload function testLib2_functions, // the exported functions NULL // no exported methods }; Running a script from the command line (under Windows XP) shows that testLoader() is invoked (it's output can be seen), however the RexxPackageUnloader testUnloader() is not (its output is missing)! > The RexxThreadContext instance is for the instance that initiated the > load operations. The load is performed > on a process basis, so you'll only see one of these. And, like all > thread context calls, any objects references > you cache in your C++ needs to be globally protected by using > RequestGlobalReference() (and released > using ReleaseGlobalReference() in the unloader). > Thanks for this hint! ... cut ... >> If so, how could one load a different set of functions/routines that are >> defined in a different package library in the same dll/so and causing the >> RexxGetPackage() to *not* be executed anymore, if a Rexx program requires >> that very same dll/so later on? >> > > Huh? A package is a self-contained entitiy, and it defines just one set of information. > If you wish to have other packages sharing code, then create a small DLL that only > defines the package functions you require but link to the larger body > of code for the actual implementation. > O.K., wanting to keep the number of dll/so at a minimum. How about the following strategy for two different use cases where a subset of external functions is the same: * define a package with the common functions that gets loaded, * if the use case is the one where additional external functions should be made available (Rexx program started from outside of Java), then in addition use the API LoadPackageFromData() loading the needed functions using a string with e.g. the following two Rexx statements: "::routine 'BsfLoadJava REGISTERED BSF4Rexx BsfLoadJava'; ::routine 'BsfUnLoadJava REGISTERED BSF4Rexx BsfUnLoadJava'; ". This could be run from the RexxPackageLoader. Would there be any side-effects to be expected if doing this? TIA. ---rony |
From: Rick M. <obj...@gm...> - 2009-04-25 14:41:20
|
On Sat, Apr 25, 2009 at 10:05 AM, Rony G. Flatscher <Ron...@wu...> wrote: > Rick McGuire wrote: > > On Sat, Apr 25, 2009 at 8:15 AM, Rony G. Flatscher > <Ron...@wu...> wrote: > > > Hi, > > a few little questions, before being able to go further at the moment: > > How would one be able to define some RexxPackageLoader function named > "testLoader" in C++ code such that it can be used in the RexxPackageEntry > field "loader"? > (Would just need the correct function header and the first statement in the > body for accessing the context object!) > > > The oorexxapi.h header defines the type signatures of the loader and > unloader function. The signatures > > typedef void (RexxEntry *RexxPackageLoader)(RexxThreadContext *); > typedef void (RexxEntry *RexxPackageUnloader)(RexxThreadContext *); > > > Thanks, this allowed me to define: > > // typedef void (RexxEntry *RexxPackageLoader)(RexxThreadContext *); > void RexxEntry testLoader (RexxThreadContext *rtc) > { > fprintf(stderr, "in testLoader() ...\n"); > fprintf(stderr, "in testLoader() rtc=[%p]...\n", rtc); > fprintf(stderr, "in testLoader() .Nil=[%s]...\n", > rtc->ObjectToStringValue(rtc->Nil())); > fflush(stderr); > } > > > // typedef void (RexxEntry *RexxPackageUnloader)(RexxThreadContext *); > void RexxEntry testUnloader (RexxThreadContext * rtc) > { > fprintf(stderr, "in testUnloader() ...\n"); > fflush(stderr); > } > > > > Using them later as: > > RexxPackageEntry testLib2_package_entry = > { > STANDARD_PACKAGE_HEADER > REXX_INTERPRETER_4_0_0, // anything after 4.0.0 will work > "testLib-AnyName", // name of the package > "0.0", // package information > testLoader, // load function > testUnloader, // unload function > testLib2_functions, // the exported functions > NULL // no exported methods > }; > > > Running a script from the command line (under Windows XP) shows that > testLoader() is invoked (it's output can be seen), however the > RexxPackageUnloader testUnloader() is not (its output is missing)! And the route to getting that fixed is to open a bug report. Note however, that the call point is the shutdown of the process Rexx environment, which is generally at process termination. Rick > > > The RexxThreadContext instance is for the instance that initiated the > load operations. The load is performed > on a process basis, so you'll only see one of these. And, like all > thread context calls, any objects references > you cache in your C++ needs to be globally protected by using > RequestGlobalReference() (and released > using ReleaseGlobalReference() in the unloader). > > > Thanks for this hint! > > ... cut ... > > If so, how could one load a different set of functions/routines that are > defined in a different package library in the same dll/so and causing the > RexxGetPackage() to *not* be executed anymore, if a Rexx program requires > that very same dll/so later on? > > > Huh? A package is a self-contained entitiy, and it defines just one set of > information. > If you wish to have other packages sharing code, then create a small DLL > that only > defines the package functions you require but link to the larger body > of code for the actual implementation. > > > O.K., wanting to keep the number of dll/so at a minimum. > > How about the following strategy for two different use cases where a subset > of external functions is the same: > > define a package with the common functions that gets loaded, > if the use case is the one where additional external functions should be > made available (Rexx program started from outside of Java), then in addition > use the API LoadPackageFromData() loading the needed functions using a > string with e.g. the following two Rexx statements: "::routine 'BsfLoadJava > REGISTERED BSF4Rexx BsfLoadJava'; ::routine 'BsfUnLoadJava REGISTERED > BSF4Rexx BsfUnLoadJava'; ". > This could be run from the RexxPackageLoader. > > Would there be any side-effects to be expected if doing this? I'm not sure what you're proposing on doing here, but the side effect is registered routines are done on a global system basis vs a package local basis as in the case with using a package loader. Also, to allow old-stile libraries to be migrated to new-style libraries, RxFuncAdd and the EXTERNAL directive will examine the dll, and if it is a new-style package (as indicated by the RexxGetPackage() entry point, it will perform the the necessary mapping to load the library and look for the reference entity in the package. As a result, you can't easily mix new-style and old-style access in the same dll. You seem dead set on spending a lot of effort to avoid using the easy (and sensible) solution. If some set of functions are not to be included in some situations, then they really are not part of the same package. > > TIA. > > ---rony > > > ------------------------------------------------------------------------------ > Crystal Reports - New Free Runtime and 30 Day Trial > Check out the new simplified licensign option that enables unlimited > royalty-free distribution of the report engine for externally facing > server and web deployment. > http://p.sf.net/sfu/businessobjects > _______________________________________________ > Oorexx-devel mailing list > Oor...@li... > https://lists.sourceforge.net/lists/listinfo/oorexx-devel > > |
From: Rony G. F. <Ron...@wu...> - 2009-04-25 16:13:27
|
>> Running a script from the command line (under Windows XP) shows that >> testLoader() is invoked (it's output can be seen), however the >> RexxPackageUnloader testUnloader() is not (its output is missing)! >> > > And the route to getting that fixed is to open a bug report. > Sure, but being new to this entire API area I was not sure whether it was indeed a bug, or whether I did something wrong or overlooked something. In the meantime not only the bug was opened, but you have fixed it faster than one can blink! :) ... cut ... > I'm not sure what you're proposing on doing here, but the side effect is registered > routines are done on a global system basis vs a package local basis as in the case > with using a package loader. > I realize that your suggestion is very helpful and would solve the problem. However, any solution should be opaque to the user of BSF4Rexx, who may just have a "::requires bsf.cls" in their Rexx programs, which then carries out all the necessary initialization. Such Rexx programs requiring the same package "bsf.cls" can be run either from the command line (and if no Java is present, it will be loaded in order to interact with it), or may be dispatched via Java (in which case Java is loaded and running already and therefore the Java loading and unloading external functions should not be made available). So, if the user should not need to be aware of these differences in the new version of BSF4Rexx, I need to adjust for it transparently for them (with the utmost goal of keeping the changes such, that all prior BSF4Rexx scripts continue to run unchanged). So that is the reason why I am trying to understand all ramifications for the different possibilities before really going to implement a solution which keeps the interfaces for the BSF4Rexx users stable. > Also, to allow old-stile libraries to be migrated to new-style libraries, RxFuncAdd and > the EXTERNAL directive will examine the dll, and if it is a new-style package (as indicated > by the RexxGetPackage() entry point, it will perform the the necessary mapping to load the > library and look for the reference entity in the package. As a result, you can't easily mix > new-style and old-style access in the same dll. You seem dead set on spending a lot of > effort to avoid using the easy (and sensible) solution. If some set of functions are not to be > included in some situations, then they really are not part of the same package. > Thank you very much indeed! ---rony |
From: Rick M. <obj...@gm...> - 2009-04-25 16:19:33
|
On Sat, Apr 25, 2009 at 12:13 PM, Rony G. Flatscher <Ron...@wu...> wrote: > > Running a script from the command line (under Windows XP) shows that > testLoader() is invoked (it's output can be seen), however the > RexxPackageUnloader testUnloader() is not (its output is missing)! > > > And the route to getting that fixed is to open a bug report. > > > Sure, but being new to this entire API area I was not sure whether it was > indeed a bug, or whether I did something wrong or overlooked something. In > the meantime not only the bug was opened, but you have fixed it faster than > one can blink! :) > > ... cut ... > > I'm not sure what you're proposing on doing here, but the side effect is > registered > routines are done on a global system basis vs a package local basis as in > the case > with using a package loader. > > > I realize that your suggestion is very helpful and would solve the problem. > > However, any solution should be opaque to the user of BSF4Rexx, who may just > have a "::requires bsf.cls" in their Rexx programs, which then carries out > all the necessary initialization. Such Rexx programs requiring the same > package "bsf.cls" can be run either from the command line (and if no Java is > present, it will be loaded in order to interact with it), or may be > dispatched via Java (in which case Java is loaded and running already and > therefore the Java loading and unloading external functions should not be > made available). > > So, if the user should not need to be aware of these differences in the new > version of BSF4Rexx, I need to adjust for it transparently for them (with > the utmost goal of keeping the changes such, that all prior BSF4Rexx scripts > continue to run unchanged). So that is the reason why I am trying to > understand all ramifications for the different possibilities before really > going to implement a solution which keeps the interfaces for the BSF4Rexx > users stable. I'm not sure how you detect which situation you're in, but you have two options: 1) In the prolog for bsf.cls you can use .context~package~loadLibrary("yada") to load the additional functions. If you need to do this in C++ code, then the LoadLibrary() API gives you the same capability from that context. Rick > > Also, to allow old-stile libraries to be migrated to new-style libraries, > RxFuncAdd and > the EXTERNAL directive will examine the dll, and if it is a new-style > package (as indicated > by the RexxGetPackage() entry point, it will perform the the necessary > mapping to load the > library and look for the reference entity in the package. As a result, you > can't easily mix > new-style and old-style access in the same dll. You seem dead set on > spending a lot of > effort to avoid using the easy (and sensible) solution. If some set of > functions are not to be > included in some situations, then they really are not part of the same > package. > > > Thank you very much indeed! > > ---rony > > > > > ------------------------------------------------------------------------------ > Crystal Reports - New Free Runtime and 30 Day Trial > Check out the new simplified licensign option that enables unlimited > royalty-free distribution of the report engine for externally facing > server and web deployment. > http://p.sf.net/sfu/businessobjects > _______________________________________________ > Oorexx-devel mailing list > Oor...@li... > https://lists.sourceforge.net/lists/listinfo/oorexx-devel > > |