如何消除OpenModelica外部函数数组输出的显式映射警告?
在OpenModelica项目中,使用单输出数组的外部函数时出现翻译警告,提示未使用显式映射,OpenModelica会将其作为输入处理但不符合Modelica规范。现有外部函数声明和对应C代码可正常编译返回值,但警告无法消除,需修改代码解决。
警告信息
[1] 18:05:18 Translation Warning
[MyModel: 3:1-11:25]: An external declaration with a single output without explicit mapping is defined as having the output as the lhs, but language C does not support this for array variables. OpenModelica will put the output as an input (as is done when there is more than 1 output), but this is not according to the Modelica Specification. Use an explicit mapping instead of the implicit one to suppress this warning.
原代码
Modelica函数声明
within MyPackage; impure function MyExternalFunction "My External Function" input Real input1 "Input 1"; input Real input2 "Input 2"; input Real input3 "Input 3"; output Real result[2] "result1, result2"; external "C" annotation( IncludeDirectory = "modelica://MyPackage/", Include = "#include \"my_code.c\"" ); end MyExternalFunction;
对应C代码
void MyExternalFunction(double input1, double input2, double input3, double* result, size_t n) { result[0] = 1.2; // result 1 result[1] = 3.4; // result 2 n = 2; }
修改方案
1. 为Modelica外部函数添加显式参数映射
核心是在external声明中明确指定参数的传递顺序和映射关系,替代默认的隐式映射。修改后的Modelica代码如下:
within MyPackage; impure function MyExternalFunction "My External Function" input Real input1 "Input 1"; input Real input2 "Input 2"; input Real input3 "Input 3"; output Real result[2] "result1, result2"; external "C" MyExternalFunction(input1, input2, input3, result, size(result)) annotation( IncludeDirectory = "modelica://MyPackage/", Include = "#include \"my_code.c\"" ); end MyExternalFunction;
这里通过MyExternalFunction(input1, input2, input3, result, size(result))明确告诉OpenModelica:将输入参数依次传递,把输出数组result和它的长度size(result)作为参数传入C函数,完全符合Modelica规范中显式映射的要求,从而消除警告。
2. 优化C代码(可选)
原C代码中n = 2;属于无效操作,因为n是传值参数,修改后无法反馈到Modelica侧。建议调整C代码,基于传入的数组长度做安全赋值,避免越界:
void MyExternalFunction(double input1, double input2, double input3, double* result, size_t n) { // 确保数组长度足够时再赋值,避免访问越界 if (n >= 1) { result[0] = 1.2; } if (n >= 2) { result[1] = 3.4; } }
内容的提问来源于stack exchange,提问作者vindarmagnus

