调试器 API - 提交调试命令 (QteSubmitDebugCommand) API

Debugger API - Submit Debug Command (QteSubmitDebugCommand) API

澄清一下,我使用的是 V7R3M0。

我正在尝试调用提交调试命令 (QteSubmitDebugCommand) API 但没有取回我期望的结果,或者我没有正确理解结果。我正在尝试按照 BREAK 语句的示例(在手册页面底部附近)。我期待与显示的结果相似,但我没有得到相同的结果。

我的原型是:

dcl-pr QteSubmitDebugCommand extproc(*dclcase);
  rcvrDta char(128);                          
  rcvrSiz int(10) const;                      
  viewID int(10) const;                       
  InputBuffer char(64) const;                 
  InpBfrSiz int(10) const;                    
  CompilerID char(20) const;                  
  apiError like(apiErrDs);                    
end-pr;                                       

变量定义为:

  dcl-pi *n ;
    pViewID int(10) const;
    pDebugCommand varchar(64) const options(*trim);  // This is BREAK 10 WHEN IDX > 2
    pCompilerID char(20) const;   // which is valid in the test harness program
  end-pi;

  dcl-s receiverVariable char(128);
  dcl-s i uns(5);

  dcl-ds apiErrDs likeDs(apiErrDsTmp) inz;

  dcl-ds resultEntryTmp template qualified;
    resultType uns(10);
    count uns(10);
    length uns(10);
  end-ds;

  dcl-s receiverPtr pointer;
  dcl-ds receiverData qualified based(receiverPtr);
    bytesReturned int(10);
    bytesAvailable int(10);
    entries int(10);
    resultArray dim(4) likeds(resultEntryTmp);
    stringSpace char(256);
  end-ds;

然后我用 API 调用:

QteSubmitDebugCommand(receiverVariable :%Len(receiverVariable) :pViewID 
                      :pDebugCommand :%Len(pDebugCommand) :pCompilerID :apiErrDS);

  receiverPtr = %addr(receiverVariable);

此时我转储程序以检查结果。

我在转储中看到的是:

RECEIVERDATA          DS
   BYTESAVAILABLE      INT(10)              57               '00000039'X
   BYTESRETURNED       INT(10)              57               '00000039'X
   ENTRIES             INT(10)              3                '00000003'X
   RESULTARRAY         DS                   DIM(4)
     (1)
       COUNT           UNS(10)              3                '00000003'X
       LENGTH          UNS(10)              0                '00000000'X
       RESULTTYPE      UNS(10)              33554432         '02000000'X
     (2)
       COUNT           UNS(10)              10               '0000000A'X
       LENGTH          UNS(10)              0                '00000000'X
       RESULTTYPE      UNS(10)              83886080         '05000000'X
     (3)
       COUNT           UNS(10)              10               '0000000A'X
       LENGTH          UNS(10)              0                '00000000'X
       RESULTTYPE      UNS(10)              83886080         '05000000'X
     (4)
       COUNT           UNS(10)              1849750016       '6E40F200'X
       LENGTH          UNS(10)              4210752          '00404040'X
       RESULTTYPE      UNS(10)              3385124672       'C9C4E740'X

STRINGSPACE 未显示,但看起来正确

按照手册是应该回来的:

Receiver Variable
Offset       Field                    Value
0            Bytes returned           59
             Bytes available          59
             Entry count              3

12           Result type              BreakR(2)
             Break results count      3
             Reserved

24           Result type              BreakPositionR(5)
             Line number              7 (in my case this = 10)
             Reserved

36           Result type              ExpressionTextR(7)
             Expression text offset   48
             Expression text length   10

48           String space    result > 5

所以看起来头记录(偏移量 0)是正确的。

resultArray(1) 看起来是正确的,因为 RESULTTYPE 的十六进制值是 '02000000'X,我认为它是 BreakR。但我期望转储中的值是 2 而不是 33554432。有人能告诉我这是为什么吗?我是做错了什么还是只是误解了它的显示方式。

resultArray(2) 看起来是正确的,因为 RESULTTYPE 的十六进制值为 '05000000'X,我认为它是 BreakPositionR。关于为什么我必须查看十六进制值的相同问题。

resultArray(3) 看起来不正确,因为 RESULTTYPE 的十六进制值为 '05000000'X,手册显示我应该期待 ExpressionTextR (7)。

至于字符串 space 我没有看到任何类似 IDX > 2 的东西,手册显示我应该期待它。

谁能看出我在调用或原型定义中做错了什么。

此外,有人可以解释为什么 resultarray.count 看起来像一个普通的 int 而 resultarray.recordtype 只在十六进制中显示正确。我应该查看十六进制值吗?

如有任何想法,我们将不胜感激。

谢谢,

罗布

更新: 在 Mark 回复后,我更改了程序以遵循 Mark 的建议并且它工作正常。谢谢,马克。

这是我结束时将代码更改为...

  dcl-s receiverPtr pointer;
  dcl-ds receiverData qualified based(receiverPtr);
    bytesReturned int(10);
    bytesAvailable int(10);
    entries int(10);
  end-ds;

  dcl-s resultEntryPtr pointer;
  dcl-ds resultEntry qualified based(resultEntryPtr);
    type uns(10) pos(1);
    count uns(10) pos(5);
    offset uns(10) pos(5);
    length uns(10) pos(9);
  end-ds;
  dcl-s stringSpace char(256);


  QteSubmitDebugCommand(receiverVariable :%Len(receiverVariable) :pViewID :pDebugCommand :%Len(pDebugCommand)
                       :pCompilerID :apiErrDS);
    receiverPtr = %addr(receiverVariable);

    resultEntryPtr = %addr(receiverVariable);

    // We want to position the pointer to the last entry which contains
    // the offset and the length of the character string.
    resultEntryPtr += 12 * receiverData.entries;
    stringSpace = %subst(receiverVariable: resultEntry.offset: resultEntry.length);  

不太确定结果数组条目的格式,但是关于这个 API 的一件事是结果数组是可变长度的,并且字符串条目紧跟在返回的结果数组之后。这意味着除非您在结果数组中恰好获得 4 个条目,否则您将不会在字符串 space 变量中以字符串 space 结束。请注意,如果您转换结果数组条目 4 x'C9C4E740 6E40F200 00404040' 中的十六进制代码,您将得到一个空终止的 EBCDIC 字符串,表示 IDX > 2。这是正确的位置,紧跟在第三个结果数组条目之后(因为 API 告诉您返回了 3 个条目)。 API 不知道你的 RPG 字段的格式,你实际上只是提供了一个你必须解释的缓冲区。

我通常使用基变量来解释诸如可变长度格式之类的东西。所以在这种情况下我会定义这样的东西:

dcl-ds resultEntry        Qualified Based(pResultEntry);
  type                    Uns(10) Pos(1);
  count                   Uns(10) Pos(5);
  offset                  Uns(10) Pos(5);
  length                  Uns(10) Pos(9);
end-ds;
dcl-s pResultEntry        Pointer;

注意 resultEntry.countresultEntry.offset 相互重叠,但在条目是具有偏移量和长度的类型 3 条目而不是仅具有计数的类型 2 条目的情况下提供好的名称.您可以不同地定义它,但关键是数据结构声明行上的 Based 关键字。

要处理这个,你可以这样做:

pResultEntry = %addr(ReceiverData);
for ix = 1 to ReceiverData.entries;
  pResultEntry += 12;
  ProcessResultArrayEntry(resultEntry);
endfor;

但正如我之前所说,我不确定您在结果数组条目 3 中看到的是什么。它似乎应该是具有偏移量和长度的 3 部分条目之一。您应该能够使用如下内容将文本从中提取出来:

string = %subst(ReceiverData: resultEntry.offset: resultEntry.length);