Кому-то удалось установить InstantObjects в Delphi XE4?

Кому-то удалось установить InstantObjects в Delphi XE4?

Я компилирую последние исходники, которые находятся в репозитории svn. После исправления некоторых проблем в версии компилятора я застрял в следующем фрагменте кода:

procedure TInstantAccessor.SetOnCompare(Value: TInstantCompareObjectsEvent);
begin
   if @Value <> @FOnCompare then
   begin
      FOnCompare := Value;
      RefreshView;
   end;
end;

В результате появляется сообщение об ошибке «[Ошибка dcc32] InstantPresentation.pas (1580): E2008 Несовместимые типы» в строке:

if @Value <> @FOnCompare then

Но они одного типа: TInstantCompareObjectsEvent

Что случилось?


person Flávio Oliveira E Santos    schedule 16.07.2013    source источник
comment
Может ли это быть ошибкой Delphi XE4?   -  person Flávio Oliveira E Santos    schedule 17.07.2013
comment
@TLama, сравнение проверяет, назначается ли снова одна и та же функция. Если не использовать @, компилятор не будет компилироваться, потому что он ожидает вызова функций. Флавио, ты дважды проверил директиву компилятора {T}? Подробнее здесь: docwiki.embarcadero.com/RADStudio/XE4/en/   -  person Fabricio Araujo    schedule 17.07.2013
comment
Я думаю, что код сравнивает, занимают ли объекты один и тот же адрес памяти...   -  person Flávio Oliveira E Santos    schedule 17.07.2013
comment
@TLama: нет проблем, бывает со всеми. ;-)   -  person Fabricio Araujo    schedule 17.07.2013
comment
@FabricioAraujo, вы имели в виду {$T}?   -  person Flávio Oliveira E Santos    schedule 17.07.2013
comment
Точно, извините за опечатку.   -  person Fabricio Araujo    schedule 17.07.2013
comment
Я установил источник dpk как {$T+}, но это не сработало...   -  person Flávio Oliveira E Santos    schedule 17.07.2013


Ответы (2)


Возможно, приведение процедурного указателя к общему типу Pointer может решить:

procedure TInstantAccessor.SetOnCompare(Value: TInstantCompareObjectsEvent);
var 
  PValue, PFOnCompare: Pointer;
begin
   PValue := Pointer(@Value);           // Casting the original pointer to an generic pointer 
   PFOnCompare := Pointer(@FOnCompare);
   if @PValue <> @PFOnCompare then
   begin
      FOnCompare := Value;
      RefreshView;
   end;
end;
person Fabricio Araujo    schedule 16.07.2013
comment
Я бы сказал, что this post может оказаться полезным. Конечно, только если целью сравнения здесь является не просто сравнение Code части метода (что делает использование оператора @ при сравнении методов). В таком случае код типа if TMethod(Value).Code <> TMethod(FOnCompare).Code then должен работать. - person TLama; 17.07.2013

То, что Фабрисио написал в комментариях, имеет смысл. Я окружил код директивами {$T-} и {$T+}, и код скомпилировался!

Теперь у меня проблемы с другими частями кода, но это уже другая история.

procedure TInstantAccessor.SetOnCompare(Value: TInstantCompareObjectsEvent);
begin
{$T-}
   if @Value <> @FOnCompare then
   begin
      FOnCompare := Value;
      RefreshView;
   end;
{$T+}
end;

Спасибо вам всем.

person Flávio Oliveira E Santos    schedule 17.07.2013
comment
Таким образом, сравнение предназначалось для нетипизированных указателей, а оператор @ (по какой-то причине) генерировал типизированные указатели... - person Fabricio Araujo; 17.07.2013