Создание DEF-файла
Рассмотрим какую-либо функцию, написанную на Pascal, например, для вычисления синуса путем разложения в ряд:
function sin1(x: Double): Double; VAR I:INTEGER; R:DOUBLE;SL:DOUBLE;XX:DOUBLE; CONST DELTA=0.0001 ; begin SL:=X; I:=1; R:=0; XX:=X*X; WHILE (ABS(SL)>DELTA) DO BEGIN R:=R+SL; SL:=-(SL*XX/(2*I))/(2*I+1); inc(i); END; result:=R; end;
Реализация ее с помощью C++ выглядит так:
double sin1(double x) { int ii; double xx,r,sl,f,delta=0.0001; sl=x; ii=1; r=0; xx=x*x; f= fabs(sl); while (f>delta) { r=r+sl; sl=-(sl*xx/(2*ii))/(2*ii+1); f=fabs(sl); ii=ii+1 ; } return(r); }
Создадим простейшее приложение для тестирования этой функции:
Рис. 10. Приложение, подлежащее разбиению на клиента и сервер функциональности
unit SINTST;
interface
uses Windows, Messages, SysUtils, Classes,Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, TeEngine, Series, ExtCtrls, TeeProcs, Chart,a1;
type TForm1 = class(TForm) Chart1: TChart; Series1: TFastLineSeries; BitBtn1: TBitBtn; procedure BitBtn1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation
{$R *.DFM}
function sin1(x: Double): Double; VAR I:INTEGER; R:DOUBLE;SL:DOUBLE;XX:DOUBLE; CONST DELTA=0.0001 ;
begin SL:=X; I:=1; R:=0; XX:=X*X; WHILE (ABS(SL)>DELTA) DO BEGIN R:=R+SL; SL:=-(SL*XX/(2*I))/(2*I+1); inc(i); END; result:=R;
end; {sin1}
procedure TForm1.BitBtn1Click(Sender: TObject); VAR I:INTEGER;X:DOUBLE;Y:DOUBLE;
begin FOR I:=1 TO 270 DO BEGIN X:=0.1*I; //Y:=SIN1(I); Y:=sin1(X); CHART1.SERIES[0].ADDXY(X,Y,FLOATTOSTR(X),clwHITE); END
end;
end.
Предположим, нам нужно разделить это приложение на сервер функциональности, вычисляющий синус, и "тонкого" клиента, рисующего график этой функции. В этом случае создание сервера функциональности следует начать с определения его интерфейса, для чего следует создать DEF-файл с описанием интерфейса этой функции на языке IDL (Interface Definition Language); вспомним, что IDL фактически представляет собой стандарт описания интерфейсов, и все его диалекты похожи друг на друга.
[ uuid(cdf19a00-22c8-11d2-a36c-008048eb72de), version(1.0) ] interface a1{ double sin1( [in] double x); }
Этот код присваивает серверу уникальный код UUID (Universal Unique Identifier), который можно сгенерировать с помощью алгоритма, определенного Open Software Foundation и реализованного в ряде утилит и функций (например, есть функция Windows API CoCreateGUID, реализующая этот алгоритм). В случае TCP-сервера в действительности он не используется, так же как и номер версии сервера, но используется в случае DCE-сервера. Затем объявляется интерфейс сервера, в котором можно описать несколько функций (в нашем случае она одна).
При написании DEF-файлов следует учитывать соответствие типов данных в DEF-файлах и используемых для создания серверных и клиентских частей языков программирования:
Объявления в DEF-файле | Входные параметры Pascal | Выходные параметры Pascal |
Short x | x: Smallint | var x: Smallint |
long x | x: Longint | var x: Longint |
int x | x: Integer | var x: Integer |
float x | x: Single | var x: Single |
double x | x: Double | var x: Double |
char x | x: Char | var x: Char |