如何转换RPGLE函数原型以从“ C”程序调用?

时间:2019-01-15 11:18:09

标签: rpgle

我有一个现有的RPGLE函数,需要从C ILE程序中调用。它返回一个数据结构,而且我似乎无法计算出C原型,因此调用看起来像什么?我试图从下面提取问题的实质。

dcl-s idT int(10) template;

dcl-s param1T char(25) template;                                                         
dcl-s param2T char(100) template;  

dcl-ds paramT qualified template; 
  param1 like(param1T);                                               
  param2 like(param2T);
end-ds;

dcl-pr fn1 likeds(paramT);                             
  id like(idT) const;                                                   
end-pr;  

我可以看到输入参数是一个指向int的指针,所以我有类似的东西...

paramT fn1(int *id);

但是返回的值不正确。

我希望计算值的值会返回到返回的数据结构中(调试调用表明正在计算正确的值 )。

编辑: 这是通话的“ C”端(几乎可以肯定是问题所在)..

typedef _Packed struct       
{                            
   char param1 ^25];        
   char param2 ^100];    
} paramt;    

paramt *FN1(const int *id);

paramt *value = FN1(&id);       

1 个答案:

答案 0 :(得分:4)

尽管RPGLE可以按值或按引用接收参数,但它始终返回一个值。因此,您应该这样定义函数:

paramt FN1(const int *id);

并这样称呼它:

paramt value = FN1(&id);

对此有一个警告。当返回简短的内容(例如char(1))时,C喜欢将字节扩展为整数,并且您可能需要在原型中添加ExtProc(*cwiden)ExtProc(*cnowiden)。更多信息here

还有案件的问题。您已在示例中正确处理了此问题,但出于完整性考虑,RPG在标识符方面不区分大小写。除非另有说明,否则它将一切都转换为大写。对于喜欢使用小写字母的C开发人员来说,这可能会令人讨厌。您可以将*dclcase添加到ExtProc,以告诉编译器不要将过程名称转换为大写,而要使用原型的大小写。所以:

dcl-pr fn1    LikeDs(paramT) ExtProc(*dclcase);
  id          Like(idT) const;
end-pr;

可以这样称呼:

paramt value = fn1(&id);

有关*dclcase here的更多信息。

最后有RTNPARM。此关键字可以添加到RPGLE过程中,以告诉其将返回值视为参数。当返回大字符串或结构以避免在栈上放置大值时,这很有用。这是一个性能问题。尽管RPGLE知道如何处理,但无法(通过原型)告诉C程序返回值在第一个参数中。您只需要编写C原型代码,即可在第一个参数位置具有一个指向返回值的指针。有关RTNPARM here的更多信息。多语言示例是CL,但是您应该能够掌握要点。