我有一个现有的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);
答案 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,但是您应该能够掌握要点。