Поиск перегруженного имени глобальной подпрограммы при наличии нескольких подключенных модулей происходит во всех модулях. При этом вначале осуществляется просмотр текущего модуля, а потом всех модулей, подключенных в секции uses, в порядке справа налево . Если при этом поиске находится объект, который не может перегружать предыдущие (например, перегружается процедура, а найдено имя переменной), то цепочка перегрузки заканчивается, и поиск наилучшей перегруженной подпрограммы идет среди найденных до этого момента. Если в модуле, откомпилированном позже, имеется подпрограмма с точно такими же параметрами, то она скрывает версию из модуля, откомпилированного раньше.
Например, пусть основная программа подключает два модуля - un1 и un2:
main.pas
usesun2,un1;
procedurep(i: integer);
begin
write(1);
end;
begin
p(2.2);
p(2);
end.
un2.pas
unitun2;
procedurep(r: real);
begin
write(3);
end;
end.
un1.pas
unitun1;
procedurep(r: real);
begin
write(2);
end;
end.
В результате будет выведено 21, что означает, что первой была вызвана процедура p из модуля un1.
Поиск перегруженного имени метода осуществляется аналогично: вначале осуществляется просмотр текущего класса, затем его базового класса и т.д. до класса Object, либо до того момента, как будет встречен объект, который не может перегружать предыдущие (имя поля или свойства). Из всех найденных таким образом одноименных методов выбирается наилучший. При этом в разных классах могут быть методы с идентичными параметрами; в этом случае вызывается первый встреченный метод от данного класса к классу Object.
Подпрограммы с переменным числом параметров также участвуют в перегрузке, однако, обычные подпрограммы имеют над ними приоритет. Например, в ситуации
procedurep(i: integer);
begin
write(1);
end;
procedurep( paramsa: array ofinteger);
begin
write(2);
end;
begin
p(1)
end.
будет вызвана первая процедура.
Вызов подпрограмм из неуправляемой dll
Для вызова подпрограммы из неуправляемой dll (содержащей обычный, а не .NET-код) используется конструкция вида:
заголовок функции external' имя dll ' name' имя функции в dll ';
Например:
functionMessageBox(h: integer; m,c: string; t: integer): integer;
external'User32.dll' name'MessageBox';
...
MessageBox(0,'Hello!','Сообщение',0);
Модули предназначены для разбиения текста программы на несколько файлов. В модулях описываются переменные, константы, типы, классы, процедуры и функции. Для того чтобы эти объекты можно было использовать в вызывающем модуле (которым может быть и основная программа), следует указать имя файла модуля (без расширения .pas) в разделе usesвызывающего модуля. Файл модуля (.pas) или откомпилированный файл модуля (.pcu) должен находиться либо в том же каталоге, что и основная программа, либо в подкаталоге Libсистемного каталога программы PascalABC.NET.
Модуль имеет следующую структуру:
unitимя модуля;
interface
раздел интерфейса
implementation
раздел реализации
initialization
раздел инициализации
finalization
раздел финализации
end.
Имеется также упрощенный синтаксис модулей без разделов интерфейса и реализации.
Первая строка обязательна и называется заголовком модуля . Имя модуля должно совпадать с именем файла.
Раздел интерфейса и раздел реализации модуля могут начинаться с раздела usesподключения внешних модулей и пространств имен .NET. Имена в двух разделах usesне должны пересекаться.
Раздел интерфейса включает объявление всех имен, которые экспортируются данным модулем в другие модули (при подключении его в разделе uses). Это могут быть константы, переменные, процедуры, функции, классы, интерфейсы. Реализация методов классов может быть дана прямо в разделе интерфейса, но это не рекомендуется.
Раздел реализации содержит реализацию всех процедур, функций и методов, объявленных в разделе интерфейса. Кроме этого, в разделе реализации могут быть описания внутренних имен, которые не видны вне модуля и используются лишь как вспомогательные.
Читать дальше