Форум: "Начинающим";
Текущий архив: 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.013 c