2009-08-24 1 views
1

Я пишу элемент управления, который должен иметь возможность отображать любой список данных. То, что я хотел сделать, заключалось в том, чтобы имитировать конструкцию for-in, в которой я проверяю публичную функцию GetEnumerator, которая содержит свойство Current и метод MoveNext.Как вызвать GetEnumerator на произвольном типе?

Я определил следующее:

  1. я могу проверить существования метода простого вызова MethodAddress на моем объекте. Если я получаю адрес, метод существует.
  2. Я могу использовать RTTI для проверки типа возвращаемого метода.
  3. Я могу использовать RTTI, чтобы проверить свойство и прочитать его.

Промежуток, хотя, я пропускаю маленькие кусочки информации:

  1. Как вызвать метод, учитывая его адрес? Могу ли я просто написать определение (например, для импорта), указать адрес и назвать его?
  2. Проверка возвращаемого типа метода требует вызова GetTypeData с его PTypeInfo. Я получаю PTypeInfo, вызывая TypeInfo для типа. Итак, как мне получить PTypeInfo для данного метода, учитывая только его адрес?
+0

Я не совсем понял, чего вы пытаетесь достичь. В вашем элементе управления отображаются данные, но куда идет перечислитель? – jpfollenius

+0

И почему бы вам просто не убедиться, что все данные, переданные вашему элементу управления, реализуют IEnumerable? Вам нужна дополнительная функциональность в вашем счетчике? Что это? – jpfollenius

+1

Планируется перечислить элементы в списке. Кроме того, я в основном буду использовать это в сочетании с большим количеством существующего кода, большинство из которых реализует GetEnumerator для включения поддержки in-in, но ни один из них не реализует IEnumerable (который не нужен или не используется встроенной конструкцией Delphi). –

ответ

2
  1. Для вызова метода, вы принимаете возвратил адрес и поместил его в указатель кода TMethod. Поместите объект в указатель данных, а затем переведите его в указатель метода с правой подписями.
  2. Чтобы проанализировать подпись функции, вам понадобится довольно сложный RTTI. Для получения дополнительной информации см. http://hallvards.blogspot.com/2006/05/hack-10-getting-parameters-of.html. Но обратите внимание на предостережение в стороне дна:

Обратите внимание, что это работает только если экземпляр (или один из его компонентов) также имеет свойство, опубликованную указует на опубликованном метод. хорошей новостью является то, что это имеет место для наиболее существующих опубликованных методов - таких как обработчики событий на экземпляре TForm . Плохая новость заключается в том, что это не было бы в случае любых опубликованных методов, которые мы хотели бы вызвать динамически во время выполнения (и, следовательно, не будет назначен ни одному событию).

То, что вы пытаетесь сделать, может оказаться невозможным при текущей модели RTTI. Но Delphi 2010, как предполагается, имеет расширенную систему RTTI, которая позволит вам делать что-то подобное намного проще, и это связано с RSN. (Раньше был отсчет релиза на сайте Embarcadero, который сегодня отсчитывает до полуночи.Тем не менее, они убрали его, поэтому я не уверен, что это официальная дата релиза или нет.)

+0

Да, ваш ответ в пункте 1 является вариантом ответа Смашера о том, что я работал (до того, как он отредактировал его). И вы абсолютно правы - мне не повезло, пока не выйдет Delphi 2010. К сожалению, это гарантировано для меня слишком поздно. Я принимаю ваш ответ, но я думаю, что я собираюсь использовать обходной путь с использованием анонимных методов. Если я заработаю, я покажу его здесь. –

1

Прежде всего обратите внимание, что RTTI доступен только для опубликованных свойств и методов.

Для вызова метода найденного по MethodAdress, просто сделать:

TMyMethod = procedure (Self : TObject; const Param : String); 
... 
var 
    MyMethod : TMyMethod; 
... 
MyMethod := Obj.MethodAdress ('MethodName'); 
if Assigned (MyMethod) then 
    MyMethod (Obj, 'Hallo'); 

Что касается вашего второго вопроса, то это может помочь:

Link

+1

Прохладный, я дам это бас. Я видел, что MethodAddress возвращает указатель и предполагает, что это будет только указатель на код. Так что же, просто ли это совместимость с TMethod, поскольку указатель данных доступен (Obj в вашем примере)? –

+0

Прости, я что-то пропустил. Отредактировал ответ. – jpfollenius

Смежные вопросы