【问题标题】:Returning arbitrary binary data from RPG program从 RPG 程序返回任意二进制数据
【发布时间】:2021-05-04 14:27:37
【问题描述】:

假设我有这个程序界面

d PgmText         pi
d  outInfo                   65535
d  pgmName                      10    const
d  pgmLibrary                   10    const

我通过JTOpen 调用它,然后读取分配给输入/输出参数outInfo 的数据。问题是%alloc-ated数据超过了outInfo的最大维度。

那么,我该怎么办? 例如。我可以将AS400ByteArray 传递为ProgramParameter.PASS_BY_REFERENCE,但是在 RPG 代码中我该怎么办?

注意它必须与 V5R1 兼容。

【问题讨论】:

    标签: ibm-midrange rpgle jtopen


    【解决方案1】:

    v5r1?真的吗?

    还要注意,将 RPG 程序中的 %alloc() 数据传回 JTOpen 是个坏主意...

    你可以有一个看起来像这样的 PI

    d PgmText         pi
    d  outInfoPtr                       *   value
    d  outInfoSize                  10i 0 const
    d  pgmName                      10    const
    d  pgmLibrary                   10    const
    

    然后使用baased变量..

    另一种选择是将数据输出到 IFS 并将文件名返回给 JTOpen。​​

    最后,如果这与您的调试器 API 问题有关……您为什么要使用 RPG 包装器?只需直接从 JTOpen 调用调试器 API。

    【讨论】:

    • 另一种选择是使用用户空间。那应该有 16MB 的大小限制。是的,就是为了这个,但是你如何直接使用 JTOpen 的调试 API 呢?也许我错过了那件作品
    • 是的,用户空间是另一种选择。您自己说过 jtopen 有一个ServiceProgramCall() 方法...并且调试器 API 包含在服务程序中...
    • 哦,是这样...我知道但不幸的是,在 V7R3 之前,用于内部调用程序的 QZRUCLSP 程序仅限于 7 个参数(通过引用)。当按值传递时,它也仅限于最多 4 个字节的参数。基本上和debug API不兼容。
    • 如果可行的话,我早就这样做了 :( 所以我将所有内容都包装在 RPG 代码中。
    • 顺便说一句,65535 已经与 V5R1 不兼容。对于该版本,它或多或少限制为 32k。有点乱。
    【解决方案2】:

    似乎最好的选择是用户空间。

    例如,假设我们需要从*PGM 对象中提取源代码,然后我们将从JTOpen 中读取该源代码。为此,我们编写了以下 RPG 程序,它给出了一个 *PGM 限定路径和一个 *USRSPC 限定路径,写入该用户空间。

    从JVM层,只需ProgramCall这个RPG程序,然后用UserSpace读取。

     h dftactgrp(*no)
    
      **
      * This program writes to a UserSpace with the following layout:
      *
      * Total lines number     | CHAR(10)
      * [for every line]
      *   Sequence number      | CHAR(6)
      *   Last edit date       | CHAR(6)
      *   Source line          | CHAR(*)  (lineLength - 12)
      *
      * @author Edoardo Luppi
      **
    
     d PgmText         pr                  extpgm('PGMTEXT')
     d  qProgramName                 20    const
     d  qUsrspcName                  20    const
     d  lineLength                   10i 0 const
    
     d PgmText         pi
     d  qProgramName                 20    const
     d  qUsrspcName                  20    const
     d  lineLength                   10i 0 const
    
      * Internal procedures
     d startSourceDebug...
     d                 pr
    
     d retrieveTextViewNumber...
     d                 pr            10i 0
    
     d retrieveViewId...
     d                 pr            10i 0
     d   viewNumber                  10i 0 value
    
     d writeLinesToUserSpace...
     d                 pr
     d   viewId                      10i 0 value
    
      /copy qcopysrc,qusrspc
      /copy qcopysrc,qdebug
    
     d errorCode       ds                  qualified
     d  bytesProvided                10i 0 inz(%size(errorCode))
     d  bytesAvailable...
     d                               10i 0 inz
     d  exceptionId                   7
     d                                1
     d  exceptionData               512
    
      * QteRetrieveModuleViews
     d vewl0100        ds                  qualified
     d  bsReturned                   10i 0 inz
     d  bsAvailable                  10i 0 inz
     d  numOfElements                10i 0 inz
    
     d vewl0100Element...
     d                 ds                  qualified based(vewl0100ElementPtr)
     d  moduleName                   10
     d  viewType                     10
     d  compilerId                   20
     d  mainIndicator                10
     d  viewTimestamp                13
     d  viewDescription...
     d                               50
     d                                3
     d  viewNumber                   10i 0
     d  numberOfViews                10i 0
    
     d vewl0100ElementPtr...
     d                 s               *
    
      * QteRetrieveViewText
     d textViewStruct  ds                  qualified
     d  bsReturned                   10i 0 inz
     d  bsAvailable                  10i 0 inz
     d  numOfElements                10i 0 inz
     d  lineLength                   10i 0 inz
    
     d textViewStructElement...
     d                 ds                  qualified based(textViewElementPtr)
     d  sequenceNum                  12
     d  sourceLine                  500
    
     d textViewElementPtr...
     d                 s               *
    
      * Common variables
     d viewId          s             10i 0 inz
     d numOfLines      s             10i 0 inz
     d returnedLib     s             10    inz
     d viewTimestamp   s             13    inz
     d receiverVar     s          32000    inz
     d textViewNumber  s              3i 0 inz
     d programName     s             10    inz
      /free
    
       programName = %subst(qProgramName:1:10);
    
       startSourceDebug();
       textViewNumber = retrieveTextViewNumber();
    
       if (textViewNumber >= 0);
         viewId = retrieveViewId(textViewNumber);
         writeLinesToUserSpace(viewId);
       endif;
    
       return;
    
      /end-free
    
      **
      * Start the debug session and register the program-stop handler exit program.
      **
     p startSourceDebug...
     p                 b
      * Program-stop handler exit program path
     d PSHEP           c                   'PGMSTOPHDLMYLIB     '
      /free
    
       reset errorCode;
       QteStartSourceDebug(PSHEP:errorCode);
    
      /end-free
     p                 e
    
      **
      * Find the *TEXT debug view's number.
      **
     p retrieveTextViewNumber...
     p                 b
     d                 pi            10i 0
     d i               s             10i 0 inz
      /free
    
       reset errorCode;
    
       QteRetrieveModuleViews(
         receiverVar:
         %size(receiverVar):
         'VEWL0100':
         qProgramName:
         '*PGM':
         programName:
         returnedLib:
         errorCode
       );
    
       vewl0100 = receiverVar;
       i = 0;
    
       dow (i < vewl0100.numOfElements);
         // 124 is the length of an element of the VEWL0100 structure
         vewl0100ElementPtr = %addr(receiverVar) + 12 + (i * 124);
    
         // We are interested in the *TEXT view only, which contains
         // sequence numbers and their associated source lines
         if (vewl0100Element.viewType = '*TEXT');
           return vewl0100Element.viewNumber;
         endif;
    
         i += 1;
       enddo;
    
       // No *TEXT view found.
       return -1;
    
      /end-free
     p                 e
    
      **
      * Get the debug View ID given its number.
      **
     p retrieveViewId...
     p                 b
     d                 pi            10i 0
     d   viewNumber                  10i 0 value
    
     d viewId          s             10i 0 inz
      /free
    
       reset errorCode;
    
       QteRegisterDebugView(
         viewId:
         numOfLines:
         returnedLib:
         viewTimeStamp:
         qProgramName:
         '*PGM':
         programName:
         textViewNumber:
         errorCode
       );
    
       return viewId;
    
      /end-free
     p                 e
    
      **
      * Writes every line of the program's source, which has a fixed width,
      * sequentially to the User Space.
      **
     p writeLinesToUserSpace...
     p                 b
     d                 pi
     d   viewId                      10i 0 value
    
     d data            s            999    inz
     d startLineNumber...
     d                 s             10i 0 inz(1)
     d linesPerPass    s             10i 0 inz
     d firstPass       s               n   inz(*on)
     d lineNumber      s             10i 0 inz
     d i               s             10i 0 inz
      /free
    
       dow firstPass or textViewStruct.bsReturned < textViewStruct.bsAvailable;
         reset errorCode;
         reset receiverVar;
    
         QteRetrieveViewText(
           receiverVar:
           %size(receiverVar):
           viewId:
           startLineNumber:
           linesPerPass:
           lineLength:
           errorCode
         );
    
         firstPass = *off;
         textViewStruct = receiverVar;
    
         if (textViewStruct.bsReturned < textViewStruct.bsAvailable);
           startLineNumber += textViewStruct.numOfElements;
           linesPerPass = 1000;
         endif;
    
         i = 0;
    
         dow (i < textViewStruct.numOfElements);
           // The length of an occurrence depends on lineLength
           textViewElementPtr = %addr(receiverVar) + 16 + (i * lineLength);
           data = textViewStructElement.sequenceNum +
                  %subst(textViewStructElement.sourceLine:1:lineLength - 12);
    
           Quschgus(
             qUsrspcName:
             10 + (lineNumber * lineLength + 1):
             lineLength:
             %subst(data:1:lineLength):
             '0':
             errorCode
           );
    
           lineNumber += 1;
           i += 1;
         enddo;
       enddo;
    
       Quschgus(qUsrspcName:1:10:%char(lineNumber):'0':errorCode);
    
      /end-free
     p                 e
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-12
      • 2013-04-08
      相关资源
      最近更新 更多