从 RPG 程序返回任意二进制数据

问题描述

假设我有这个程序界面

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。

解决方法

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。

,

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

例如,假设我们需要从 *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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...