Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.01.14;
Скачать: [xml.tar.bz2];

Вниз

Вместо локальной функции как параметра   Найти похожие ветки 

 
Vovan #2   (2006-12-21 14:45) [0]

Задача.

Есть некоторая функция, которая принимает в качестве параметра имя графического файла, открывает его (например, в TBitmap) и вызывает другую процедуру обработки, которая вернёт некоторые данные об этом изображении через изменяемый параметр. Эта процедура сделана универсально - она не работает с конкретным типом графического контейнера, а осуществляет доступ к пикселям через функцию вида GetPixel(x,y: Integer): Integer, переданную в качестве параметра в процедуру.

Загвоздка в том, что нужно где-то написать эту функцию доступа к пикселям, но Delphi не даёт использовать локальную функцию. А если выносить, то и объект-контейнер должен оказаться вне большой функции, а кто о нём заботиться будет.

Вопрос. Как организовать всё это дело в данном случае?


 
Сергей М. ©   (2006-12-21 14:54) [1]


> Delphi не даёт использовать локальную функцию


Это как ?

Прямо так и заявляет, мол, не даю и всё тут ?!

Экая скромница она, однако)


 
Vovan #2   (2006-12-21 14:57) [2]

Так и заявляет.

[гога] Local procedure/function GetPixel assigned to procedure variable


 
tesseract ©   (2006-12-21 15:02) [3]

А процедура объявлена как of object?


 
MBo ©   (2006-12-21 15:09) [4]

внутренние (локальные) функции действительно нельзя (опасно) использовать в качестве процедурных параметров, однако если очень хочется:

function Calc(a: Integer; func: TАunc): Integer;
begin
 Result := 3* func(a);
end;

procedure TForm17.Button2Click(Sender: TObject);

function F(a: Integer): Integer;
begin
 Result := a + 10;
end;

begin
 Caption := IntToStr(Calc(1, @F));
end;


 
Vovan #2   (2006-12-21 15:11) [5]

>А процедура объявлена как of object?

Нет.


type
 TGetPixelProc = function (x, y: Integer): Integer;

procedure Obrabotka(var RS: TMyResult; callGetPixel: TGetPixelProc);

function ObrabotkaOfBitmap: TMyResult;
var
 TempBmp: TBitmap;

 function GetPixel(x,y: Integer): Integer;
 begin
   if TempBmp.Canvas.Pixels[x,y] = clWhite then
     Result := Zero else Result := 1;
 end;

begin
  Obrabotka(Result, GetPixel);
end;



 
Vovan #2   (2006-12-21 15:15) [6]

>MBo © (21.12.06 15:09) [4]

Можно попробовать. Но всё равно, как переделать так, чтобы:
а) Сохранить универсальность обработки (не писать кучу override).
б) Не возиться с освобождением объектов???


 
MBo ©   (2006-12-21 15:20) [7]

>Можно попробовать.
Приведенный мной пример работает позволяет обойти ограничение компилятора, но, наверно, стоит идеологию все же поменять.
Мне не вполне ясна картина того, что ты хочешь сделать, но загляни, как сделано обращение к пикселам в зависимости от цветового формата тут:
http://www.delphimaster.ru/articles/pixels/index.html


 
ors_archangel ©   (2006-12-21 15:39) [8]

Здесь можно изменить GetPixel - передавать дополнительный параметр, определяющий контейнер, т.о. функция, которая вызывает GetPixel будет передавать ему дополнительный параметр, но всё так же останется универсальной?
Мне то ж такие грабли часто мешали. Думаю, дело в том, что локальные процедуры как бы закреплены в некотором локальном пространстве имён, т.е. локальная функция имеет доступ к локальным переменным функции, по отношению к которой она является локальной, но, когда данная функция вызывается на другом уровне пространства имён, любой доступ к внешним (не глобальным) переменным может оказаться ошибочным, т.к. доступ к локальным переменным происходит по косвенной адрессации типа [ebp+xx], с другой стороны, допустим, функция LocFunc - локальна относительно функции ExFunc, во время существования (доступности) LocFunc область локальной памяти ExFunc фиксировано в памяти (внутри стека), поэтому, если бы функция могла узнать адрес любой родительской (не по вызовам, а иеархически) локальной обалсти памяти, то при досупе к внешним переменным вместо адрессации [ebp+xx] можно было бы использовать адрессацию по этому адресу, взятом в качестве базы, т.е. для решения проблемы в данном виде нужно иметь, например, односвязанный список, хранящий адреса локальных областей переменных, причём этот список может генерироваться только во время выполнения, и заполняться его элементы должны при входе в функцию (например, в прологе), это довольно рассточительно, но так можно было бы сделать использование локальных функций более ортогональным в отношении ко глобальным?


 
ors_archangel ©   (2006-12-21 15:48) [9]

Я имел в виду

type
TGetPixelProc = function (obj: TObject; x, y: Integer): Integer;// универсально

procedure Obrabotka(var RS: TMyResult; callGetPixel: TGetPixelProc; param: TObject);
begin
{ здесь любое обращение к GetPixel выглядет так: }
 GetPixel(param,x,y)
end;

function ObrabotkaOfBitmap: TMyResult;
var
TempBmp: TBitmap;

function GetPixel(bmp: TBitmap; x,y: Integer): Integer;
begin
  if bmp.Canvas.Pixels[x,y] = clWhite then
    Result := Zero else Result := 1;
end;

begin
 Obrabotka(Result, @GetPixel, TempBmp);
end;


 
Vovan #2   (2006-12-25 17:06) [10]

Я не понимаю, почему вызов
Obrabotka(Result, @GetPixel, TempBmp);
как в [9] без @ выдаёт ошибку о несовместимости типов, а с @ - нет?



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2007.01.14;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.012 c
1-1164358778
bva
2006-11-24 11:59
2007.01.14
Длинная строка в ComboBox


2-1166706904
САМАТ
2006-12-21 16:15
2007.01.14
Как создать таблицу?


2-1166529073
~Димас~
2006-12-19 14:51
2007.01.14
Интеграция


2-1166771534
Officeman
2006-12-22 10:12
2007.01.14
форматирование строки. strtoint


11-1143467110
nester
2006-03-27 17:45
2007.01.14
RegKeyGetBinary работает?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский