2.7.7 外部函数
模型中除了可以调用使用Modelica语言编写的函数外,还可以调用其他语言(目前支持C和FORTRAN 77)编写的函数,这些其他语言编写的函数称为外部函数。Modelica中调用外部函数通过Modelica函数进行,这种Modelica函数没有算法(algorithm)区域,取而代之的是外部函数接口声明语句“external”,用于表示调用的是外部函数。
函数myfuncs.sin调用C语言函数sin,调用形式为“y=sin(x)”。在external中可选地指定外部函数的语言、外部函数调用声明等。
“FORTRAN 77”是外部函数语言声明,没有语言声明时,取默认值“C”。“FORTRAN 77”后跟外部函数调用声明,说明Modelica调用实参如何传递给外部函数。注解用来指定数组布局(arrayLayout)是按行主存储(rowMajor)还是按列主存储(columMajor)、外部函数所需的头文件(Include)、外部函数所需的库文件(Library)、外部函数所需头文件所在的位置(IncludeDirectory)、外部函数所需库文件所在的位置(LibraryDirectory)。
如果没有IncludeDirectory注解,外部函数所需头文件默认位置是包含外部函数的包(package)文件(“.mo”)所在文件夹中的“Resources/Include”子文件夹。同样,若没有LibraryDirectory注解,外部函数所需库文件默认位置是包含外部函数的包(package)文件(“.mo”)所在文件夹中的“Resources/Library”子文件夹,不同平台的目标文件还可以存放在相应的平台文件夹中。支持以下标准平台:
(1)Win32[32位Microsoft Windows]。
(2)Win64[64位Microsoft Windows]。
(3)Linux32[Intel 32位Linux]。
(4)Linux64[Intel 64位Linux]。
下例中外部函数有Include、Library注解,但没有IncludeDirectory、LibraryDirectory注解,头文件和库文件存放在默认的位置。
ExternalFunctions包和其他相关文件存放的文件夹结构如下(加粗的是文件夹,缩进表示文件夹中的文件或子文件夹):
没有外部函数调用声明时,调用外部函数就按默认的方式进行:
(1)如果只有一个输出形参,输出形参作为返回值,输入形参依次传递给外部函数(如myfuncs.sin);否则,输入/输出形参依次传递给外部函数。
(2)对于返回值和标量参数,Modelica参数与外部函数参数一一对应,参数映射关系分别见表2-17、表2-18。类型中,“T”表示Modelica标量类型。
表2-17 返回值映射
表2-18 标量参数映射
(3)对于数组参数,Modelica数组除了传递数组外,还要在其后依次传递数组各维的长度,数组参数映射见表2-19。
表2-19 C数组参数映射
(4)表2-20类型中“T”表示Modelica标量类型,“T”表示对应语言的输入标量类型。
表2-20 FORTRAN 77数组参数映射
注意,Modelica和C语言的数组布局默认是行主存储,FORTRAN默认是列主存储。函数调用声明中的参数只允许变量、标量常量、返回标量的size函数。
需要特别注意的是,Modelica不允许在函数中改变输入形参的值。如果外部函数的形参是输入/输出类型(如FORTRAN 77函数DGETRF的形参A),不能直接将输入形参传递给外部函数,而应该传递输出形参并在传递参数之前使输出形参等于输入形参(如函数dgetrf的输出形参LU)。