#delphi
#delphi
Вопрос:
Я не очень хороший программист на Delphi, я рад программировать на C Builder, delphi — не мой язык. У меня есть некоторые компоненты, написанные на Delphi, и они отлично компилируются в 10.3, но я получаю ошибки в 10.4, и я вижу причину проблемы, но я понятия не имею, как это исправить. Пожалуйста, помогите мне это исправить.
procedure CopyInterlacedRGB8(const Pass: Byte; Src, Dest, Trans, Extra: pChar)
Dest^ := Char(fOwner.GammaTable[pByte(Longint(Src) 2)^]); inc(Dest); // changed these two, but I have no clue what I'm doing lul
Dest^ := Char(fOwner.GammaTable[pByte(Longint(Src) 1)^]); inc(Dest);
Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) )^]; inc(Dest); // ERROR here
Как я вижу здесь, насколько я понимаю в C , инициализируется байт, и он присваивается. Аналогично char(‘a’) = 5; Но я могу видеть, что код изначально хочет сделать, назначить что-то адресу Dest.
Как я должен изменить этот материал, чтобы он работал??
Комментарии:
1. Какие ошибки вы получаете?
2. Вы забыли сообщить нам, какую ошибку вы получили. Тем не менее,
Dest
этоPChar
, поэтомуDest^
этоChar
. Это двухбайтовое значение, поэтому вы не можете преобразовать его вByte
.3. Если вы не имеете дело с 16 / 48bit RGB, все эти переменные просто хотят иметь дело с байтами, а не со словами. Используйте
PAnsiChar
вместоPChar
— имя вашей функции в любом случае указывает на 8 бит.4. Этот код в любом случае выглядит дефектным, даже если вы можете заставить его скомпилироваться.
Char
имеет ширину в два байта в обеих версиях, на которые вы ссылаетесь. Вы, вероятно, захотите не только скомпилировать код, но и заставить его работать!5. @AmigoJack OP манипулирует данными в байтах RGB. Они не должны использовать
Char
илиPAnsiChar
— это строковые типы для символов и текста.Byte
иTBytes
было бы подходящим. Нет разумного решения сpChar
в качестве аргумента, поэтому принципиально этот метод никогда не может быть полезным. Способ разработки замены для него будет зависеть от контекста, в котором вы работаете. Первым шагом должен быть выбор подходящего типа аргумента.
Ответ №1:
Вы не дали объявление GammaTable
. Я создал тот, который кажется подходящим. Я не инициализировал его здесь, но он должен быть в вашем коде. Если ваше объявление отличается, возможно, мой код должен быть изменен.
var
GammaTable : array [Byte] of Byte;
procedure CopyInterlacedRGB8(const Pass: Byte; Src, Dest, Trans, Extra: pChar);
var
BDest : PByte;
begin
BDest := PByte(Dest);
BDest^ := GammaTable[PByte(UIntPtr(Src) 2)^]; Inc(BDest);
BDest^ := GammaTable[PByte(UIntPtr(Src) 1)^]; Inc(BDest);
BDest^ := GammaTable[PByte(UIntPtr(Src) )^]; Inc(BDest);
end;
Я не изменил тип аргументов в функции, но наверняка Src
и Dst
должно быть PByte
не PChar
. В любом случае, написанный мной код будет работать одинаково хорошо, каким бы он ни был, при условии, что он содержит желаемую исходную и целевую таблицы.
Я ввел BDest
переменную, чтобы сделать код более читаемым.
Обратите внимание, что если Src
объявлено как PByte
и {$POINTERMATH ON}
, то код может быть упрощен:
PByte(UIntPtr(Src) 2)^
становится
Src[2];
Таким образом, процедура может быть переписана следующим образом:
{$POINTERMATH ON}
procedure CopyInterlacedRGB8_(const Pass: Byte; Src, Dest : PByte; Trans, Extra: pChar);
begin
Dest[0] := GammaTable[Src[2]];
Dest[1] := GammaTable[Src[1]];
Dest[2] := GammaTable[Src[0]];
end;
Гораздо более читабельный, не так ли?
Комментарии:
1.
PByte
объявляется с{$POINTERMATH ON}
уже включенным на нем, поэтому вам не нужно вручную включать математику указателей в вашем собственном коде, чтобы использовать математику указателей дляPByte
переменной.2. @RemyLebeau Полезно знать!
3. Я бы, вероятно, просто сбросил ненужные параметры
Trans
иExtra
— по крайней мере, для этого примера они совершенно бессмысленны. OP не показал нам никакого кода, который требует их.