如何转换从 'C' 程序调用的 RPGLE 函数原型?

How to convert an RPGLE function prototype to be called from a 'C' program?

我有一个现有的 RPGLE 函数,我需要从 C ILE 程序中调用它。它 returns 一个数据结构,我似乎无法弄清楚 C 原型是什么,因此 call 会是什么样子?我试图提取下面问题的本质。

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);       

虽然 RPGLE 可以按值或按引用接收参数,但它始终 return 是一个值。所以你应该这样定义函数:

paramt FN1(const int *id);

并这样称呼它:

paramt value = FN1(&id);

对此有一个警告。当 returning 一些较短的东西时,比如 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 过程中的关键字,以告诉它把 return 值当作一个参数。这在 returning 大字符串或结构以避免在堆栈上放置大值时很有用。这是一个性能问题。虽然 RPGLE 知道如何处理这个问题,但没有办法(通过原型)告诉 C 程序 return 值在第一个参数中。您只需编写 C 原型代码,使其在第一个参数位置有一个指向 return 值的指针。有关 RTNPARM here 的更多信息。多语言的例子是CL,不过你应该能明白要点。