Внешние функции и процедуры |
Top Previous Next |
Внешняя функция или процедура – это подпрограмма, реализованная вне AnyDynamics с использованием сторонних инструментальных средств (C#, Delphi, Fortran и т.д.). Использование внешних процедур и функций показано в демо-примере "ExtFun".
В качестве определения внешней функции или процедуры в классе или пакете указывается только спецификация подпрограммы. Реализация внешней функции или процедуры должна находиться в динамической библиотеке (DLL), которую необходимо поместить в папку модели.
Функция, реализующая внешнюю функцию или процедуру, должна экспортироваться из DLL и иметь тип вызова stdcall. Формальные параметры должны соответствовать внутреннему представлению типов формальных параметров в определении внешней функции или процедуры (см. ниже). Параметры вида out и in out а также матрицы, записи и массивы в реализующей функции должны передаваться по адресу.
Пример определения внешней функции:
public function xlim(in x: double; in a: double) return double is external "ExampleDll.dll"; -- Ada
public extern double xlim(double x, double a) "ExampleDll.dll"; -- C#
Внутреннее представление скалярных типов:
•для модельного типа double используется программный тип "64-разрядное вещественное число" (double для Pascal и C#); •для модельных типов integer, byte, short используется программный тип "32-разрядное целое" (integer для Pascal, int для C#); •для модельного типа boolean используются программные типы boolean для Pascal и bool для C#; •для модельных типов string, char используются программные типы widestring для Pascal и string для C#; •для перечислимых типов используется целое число – номер перечислимого литерала, отсчитываемый от нуля.
Внутреннее представление векторов и матриц:
Значения матриц и векторов представляются двумерными вариантными массивами размерности 1..N, 1..M с элементами типа double. Для векторов M=1.
Pascal
Для получения значения элемента [i,j] из внутреннего представления значения матрицы используйте индексацию:
var MX: variant; var x: double; ... x:=MX[i,j];
Для создания внутреннего представления матрицы размерности [N,M] используйте функцию VarArrayCreate:
MX:=VarArrayCreate([1,N,1,M],varDouble); .. MX[1,3]:=2.87; ..
C#
Для получения значения элемента [i,j] из внутреннего представления значения матрицы используйте стандартный класс Array:
object MX; double x; .. x = (double)(MX as Array).GetValue(i,j);
Для создания внутреннего представления матрицы размерности [N,M] используйте метод CreateInstance:
int[] ss = {N, M}; int[] lb = {1,1}; MX = Array.CreateInstance(typeof(double), ss, lb); (MX as Array).SetValue(2.87, 1, 3); // MX[1,3] == 2.87
Внутреннее представление записей:
Значения записей представляются двумерными вариантными массивами размерности 0..N-1, 0..1, где N – число компонентов записи, с элементами типа variant или object.
Элемент [i,0] содержит имя i-го компонента записи в 16-битном представлении. Элемент [i,1] содержит значение i-го компонента записи в представлении, соответствующем его типу.
Пусть type TR is record D: double; I: integer; B: boolean; S: string; end record; ... R: TR := {D=>0.3,I=>5,B=>true,S=>"ABC"};
Pascal
var R: variant; var D: double; var I: integer; var B: boolean; var S: widestring; .. D:=R[0,1]; I:=R[1,1]; B:=R[2,1]; S:=R[3,1]; ... R:=VarArrayCreate([0,3,0,1],varVariant); R[0,0]:="D"; R[0,1]:=D; R[1,0]:="I"; R[1,1]:=I; R[2,0]:="B"; R[2,1]:=B; R[3,0]:="S"; R[3,1]:=S;
C#
object R; double D; int I; bool B; string S; .. D = Convert.ToDouble((R as Array).GetValue(0,1)); I = Convert.ToInt32((R as Array).GetValue(1,1)); B = Convert.ToBoolean((R as Array).GetValue(2,1)); S = Convert.ToString((R as Array).GetValue(3,1)); ... int[] ss = { 4, 2 }; int[] lb = { 0, 0 }; R = Array.CreateInstance(typeof(object), ss, lb); (R as Array).SetValue("D", 0, 0); (R as Array).SetValue(D, 0, 1); (R as Array).SetValue("I", 1, 0); (R as Array).SetValue(I, 1, 1); (R as Array).SetValue("B", 2, 0); (R as Array).SetValue(B, 2, 1); (R as Array).SetValue("S", 3, 0); (R as Array).SetValue(S, 3, 1);
Внутреннее представление массивов:
Значения массивов представляются одномерными массивами размерности 0..N-1, где N – число элементов в массиве, с элементами типа variant или object. I-й элемент вариантного массива содержит значение i-го элемента массива в модели в представлении, соответствующем его типу.
Пусть
AD: array of double; AR: array of TR;
Pascal
var AD: variant; var AR: variant; var R: variant; var D: double; var I: integer; ... D:=AD[2]; R:=AR[1]; I:=R[1,1]; .. AD:=VarArrayCreate([0,3],varVariant); AR:=VarArrayCreate([0,3],varVariant); .. AD[2]:=D; AR[1]:=R;
C#
object AD; object AR; object R; double D; int I; .. D = Convert.ToDouble((AD as Array).GetValue(2)); R = (AR as Array).GetValue(1); I = Convert.ToInt32((R as Array).GetValue(1,1)); ... int[] ss = { 4 }; int[] lb = { 0 }; AD = Array.CreateInstance(typeof(object), ss, lb); AR = Array.CreateInstance(typeof(object), ss, lb);
(AD as Array).SetValue(D, 2); (AR as Array).SetValue(R, 1);
|