2008-12-14 2 views

ответ

6

Это просто мнение, исходя из моего опыта того, какие варианты могут и не могут сделать.

Если вы поместите в него COM-объект, он будет сохранен в качестве ссылки IDispatch, и, таким образом, любые вызовы методов или свойства, которые вы получите на этом объекте, будут преобразованы в некоторый код, который ищет внутренний DISPID метода/свойство, массив с аргументами метода будет сконструирован, и метод будет вызван через интерфейс IDispatch.

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

Однако для обычных объектов Delphi все становится сложнее. Вы можете использовать RTTI для поиска и вызова опубликованных методов и свойств, но это все. Если у вас есть имя не опубликованного, не виртуального метода, Delphi не может найти для него правильный адрес в вашем методе.

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

Я знаю, что если вы правильно реализуете IDispatch, вы можете безопасно хранить и использовать объект через вариант. У меня есть класс, который можно использовать в качестве базового класса для объектов Delphi, для которого вы хотите это сделать. Он автоматически выведет опубликованные методы/свойства, и вы можете добавить больше, если хотите, через некоторые защищенные вызовы методов. Если есть интерес к такому классу, я могу разместить его где-нибудь.

Но опять же, это через IDispatch, и он использует опубликованные методы, остальное - это ручной код, поэтому поддержка вариантов должна быть встроена в ваши объекты, вами.

Вот почему я думаю, что они только что сказали: это просто вызовет жалобы, что мы можем держать объект, но это просто бесполезно.

Но это только мои мысли. Возможно, у кого-то чиновника есть намного лучший ответ.

+4

Вы довольно много прав. Вы также должны указать классы TCustomVariantType и TInvokeableVariantType. Эти классы показывают все, что должен был бы сделать класс, чтобы быть * использованным * (а не только сохраненным) в варианте, без необходимости реализации IDispatch. – 2008-12-14 17:34:00

+0

+1 для Rob: TCustomVariantType и TInvokeableVariantType довольно мощные. Некоторые штрафы за производительность, но которые [могут обойтись с хакерами низкого уровня] (http://blog.synopse.info/post/2011/07/01/Faster-variant-late-binding). – 2013-10-10 06:47:04

24

Вы можете указать магазин объект внутри переменной Variant - просто введите его в NativeUInt. Во всяком случае, объект является всего лишь указателем.

obj := TObject.Create; 
v := NativeUInt(obj); 
obj := TSomeObject(NativeUInt(v)); 
6

я использовал Варианты для хранения объектов в прошлом, используя внутренние Variant, код что-то вроде этого:

var 
    MyObject: TMyObject; 
    Value: Variant; 
begin 
    MyObject:= TMyObject.Create; 
    TVarData(Value).VType:= VarByRef; 
    TVarData(Value).VPointer:= MyObject; 
Смежные вопросы