Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.12.12;
Скачать: CL | DM;

Вниз

Создание интерфейса без сохранения в переменную   Найти похожие ветки 

 
bss   (2010-08-31 16:28) [0]

Забавную обнаружил ситуацию. Подключаем модуль "ComObj", пишем код:

procedure TForm1.FormCreate(Sender: TObject);
begin
 CreateOleObject("Msxml2.DOMDocument.4.0") as IDispatch ;
 CreateOleObject("Msxml2.DOMDocument.4.0") as IDispatch ;
end;


Получаем ошибку компиляции:

[Pascal Error] Unit1.pas(28): E2014 Statement expected, but expression of type "IDispatch" found

Переделываем код:

procedure TForm1.FormCreate(Sender: TObject);
begin
 CreateOleObject("Msxml2.DOMDocument.4.0") as IDispatch ;
 CreateOleObject("Msxml2.DOMDocument.4.0") ;
end;


Теперь ошибки нету )))
Зато вот так:

procedure TForm1.FormCreate(Sender: TObject);
begin
 CreateOleObject("Msxml2.DOMDocument.4.0")  ;
 CreateOleObject("Msxml2.DOMDocument.4.0") as IDispatch ;
end;


Ошибка опять есть :-) У кого какие догадки? )

P.S. Эксперименты проводились на BDS 2006


 
Сергей М. ©   (2010-08-31 16:42) [1]

В D7 утверждение


> Переделываем код:
>
> procedure TForm1.FormCreate(Sender: TObject);
> begin
>  CreateOleObject("Msxml2.DOMDocument.4.0") as IDispatch
> ;
>  CreateOleObject("Msxml2.DOMDocument.4.0") ;
> end;
>
> Теперь ошибки нету


не соответствует действительности.

Да и к чему вообще подобные бестолковые по сути "кододвижения" ?)


 
bss   (2010-08-31 17:12) [2]

не понял вопроса


 
Сергей М. ©   (2010-08-31 17:15) [3]

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


 
bss   (2010-08-31 21:20) [4]

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

Только это не важно, причем тут смысл. Вопрос в том, почему компилятор так странно себя ведет, причем тут наличие / отсутствие ключевого слова "as" и зачем он так неправильно ругается.


 
Rouse_ ©   (2010-08-31 21:41) [5]

Отписывайся на кодецентрале - это самый правильный подход к решению проблемы.


 
Игорь Шевченко ©   (2010-08-31 22:08) [6]


> В данном конкретном случае - есть ли поддержка MSXML 4.


Succeeded(CLSIDFromProgID("Msxml2.FreeThreadedDOMDocument.4.0"), ...)


 
Игорь Шевченко ©   (2010-08-31 22:09) [7]

Чего только Кулибины не наизобретают


 
Сергей М. ©   (2010-09-01 09:40) [8]


> возможно ли на этом компьютере создание этих объектов или
> нет


Ну, предположим, возможно. Предположим даже что такой извращенский способ для проверки как попытка создать собственно объект имеет право на жизнь.
Но зачем запрашивать у объекта диспинтерфейс ?)
Ведь ежу понятно, что этот объект, коль скоро он олей-объект и успешно создан, обязан реализовывать диспинтерфейс !
Как говорится, "понятно что лошадь, но только с рогами"
))


 
bss   (2010-09-01 10:43) [9]


> Succeeded(CLSIDFromProgID("Msxml2.FreeThreadedDOMDocument.
> 4.0"), ...)

это не эквивалентная проверка.


> Ну, предположим, возможно. Предположим даже что

Сергей, неужели это так сложно осознать. Тут дело не в функциональности кода, а в парадоксе с компилятором. Вопрос ставится не почему надо приводить к IDispatch, а почему компилятор при приведении не может скомпилировать код, а без приведения компилирует на ура.

P.S. Был тут парень 0xffffff или как-то так, любил такие дела. Думаю, он бы разъяснил, может появится )


 
oxffff ©   (2010-09-01 10:46) [10]

Я всегда здесь.


 
oxffff ©   (2010-09-01 10:47) [11]


> bss   (01.09.10 10:43) [9]
>
> > Succeeded(CLSIDFromProgID("Msxml2.FreeThreadedDOMDocument.
>
> > 4.0"), ...)
>
> это не эквивалентная проверка.


С этим согласен.


 
Игорь Шевченко ©   (2010-09-01 10:50) [12]


> почему компилятор при приведении не может скомпилировать
> код, а без приведения компилирует на ура


очевидно потому что интерфейс является типом с управляемым временем жизни ?


> это не эквивалентная проверка.


не знаю, руководствовались фразой
"To use version 4.0, applications must be written to use the appropriate version-dependent class IDs (CLSIDs) and ProgIDs that reference Msxml4.dll. "

из http://support.microsoft.com/kb/305019


 
Сергей М. ©   (2010-09-01 10:58) [13]


> bss   (01.09.10 10:43) [9]


Так а причем здесь тогда CreateOleObject и создание интерфейса ?
С тем же "успехом" не компилируется любое выражение вида

SomeIntferfacedObject as ISomeInterface;

гда SomeIntferfacedObject - любое выражение, имеющее итерфейсный тип


 
oxffff ©   (2010-09-01 10:59) [14]

Другой вопрос как решают разработчики компилятора как поступить в данной ситуации CreateOleObject(const ClassName: string): IDispatch;
А поскольку результатом может быть любой подтип IDispatch, то должны они решать производить вызов as IDispatch, который транслируется в вызов функции. А управляемые результаты функций сохраняются во временных переменных. Поэтому по мне это некакая несогласованность поведения
компилятора имеется.


 
oxffff ©   (2010-09-01 11:01) [15]

Собственно наличие корректных записей в реестре progId to ClassID совсем не означает, что объект будет успешно создан. Увы.


 
Игорь Шевченко ©   (2010-09-01 11:03) [16]


> Собственно наличие корректных записей в реестре progId to
> ClassID совсем не означает, что объект будет успешно создан.
>  Увы.


почему не будет ?


 
oxffff ©   (2010-09-01 11:06) [17]

Но они судя по всему делают иначе. Однако никто не мешает в дебрях
as ->GetInterface сделать некие побочные действия, а не только вернуть интерфейс. Опять же это решение разработчиков компилятора.


 
bss   (2010-09-01 11:07) [18]


> очевидно потому что интерфейс является типом с управляемым
> временем жизни ?

Вы, Игорь, первый пост то хоть читали, прежде чем начать критиковать? )))

CreateOleObject вообще-то и так возвращает IDispatch. Я просто утрировал пример до невозможности - взял и проверил IDispatch на то, что он IDispatch. И от этой проверки код почему-то перестает компилироваться.


 
oxffff ©   (2010-09-01 11:08) [19]


> Игорь Шевченко ©   (01.09.10 11:03) [16]
>
> > Собственно наличие корректных записей в реестре progId
> to
> > ClassID совсем не означает, что объект будет успешно создан.
>
> >  Увы.
>
>
> почему не будет ?


А вы знаете устройство произвольного объекта?
Он или внутренние настройки могут быть просто повреждены. Не задумывались над этим?


 
Сергей М. ©   (2010-09-01 11:10) [20]


> oxffff ©   (01.09.10 11:01) [15]


Не согласен.
Никто не заставляет пользовать штатный механизм разрешения имени объекта в CLSID через реестр.
Модуль с нормально функционирующей фабрикой требуемого класса может жить где угодно и даже не быть прописанным в реестре. И это вовсе не мешает успешному созданию объекта.


 
Игорь Шевченко ©   (2010-09-01 11:10) [21]


> Он или внутренние настройки могут быть просто повреждены


DLL может быть удалена с диска...


 
bss   (2010-09-01 11:11) [22]


> С тем же "успехом" не компилируется любое выражение вида

Ну блин. Давай заново. Вот это:

CreateOleObject("Msxml2.DOMDocument.4.0") as IDispatch

успешно компилируется.

А если написать таких строчек два раза:

CreateOleObject("Msxml2.DOMDocument.4.0") as IDispatch;
CreateOleObject("Msxml2.DOMDocument.4.0") as IDispatch ;


то уже ошибка компиляции. Именно это и кажется мне забавным.


 
oxffff ©   (2010-09-01 11:13) [23]

1. Модуль может быть поврежден.
2. Что-то может отсутствовать для корректного создания модуля и его работы.


 
oxffff ©   (2010-09-01 11:13) [24]


> модуля

объекта


 
Сергей М. ©   (2010-09-01 11:15) [25]


> bss   (01.09.10 11:11) [22]


Ну дык мне понятно что это дикость, характерная по кр.мере для BDS 2006)

Ибо, скажем, компилятор в составе D7 в подобной ситуации ведет себя вполне адекватно - на первой же строчке с подобным приведением типа дает ожидаемый отлуп.


 
Игорь Шевченко ©   (2010-09-01 11:21) [26]

D2010 честно ругается на первой же строке


 
oxffff ©   (2010-09-01 11:26) [27]

Однако более страшная ситуация была у меня недавно с generics.
Есть параметризованный класс

A<T>=class(..)
..
FieldA:T;
....
constructor create(..)
end;

B<T>=classA<T>
FieldB:Boolean;
constructor create(..)
end;

constructor B<T>create(..)
begin
Inherited create(..);
//Даже если явно сделать так, хотя там и так false
FieldB:=false;
end;

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

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

A<T>=class()
..
FieldB:Boolean;
FieldA:T;
end;

Internal error меня уже не раздражают. Я просто не обращаю на них внимание. Полный Rebuild или перезапуск среды помогает. Вот так и работаем.


 
Игорь Шевченко ©   (2010-09-01 11:30) [28]

oxffff ©   (01.09.10 11:26) [27]

Качай XE, там 70 багов с generics поправлено по свидетельству очевидцев


 
oxffff ©   (2010-09-01 11:35) [29]

Есть потенциальная опасность, на которую я попал вчера. Как раз производя работы по добавлению параметрических функций
к своему языку YAR(еще в работе).

TSomeClass<T:class,constructor>=class
value:T;
end;

construtor TSomeClass<T>.create
begin
value:=T.create;
end;

У меня в коде было так
SomeClass<Tdictionary<string,TTypeParameter>>

Но увы после конcтруктора value будет неполностью иниализированным.
Не смотря на корректность, если сделать так.

Tdictionary<string,TTypeParameter>.create()

Но это не баг. Это просто недоработка Tdictionary.

Вообщем обошел просто

SomeClass:=TSomeClass<..>.create(..)
SomeClass.value.create(); <- доинициализация. Хотя это может работать не во всех случаях, если есть завязки на AfterContruction.

Решаем проблемы сами.


 
oxffff ©   (2010-09-01 11:36) [30]


> Игорь Шевченко ©   (01.09.10 11:30) [28]
> oxffff ©   (01.09.10 11:26) [27]
>
> Качай XE, там 70 багов с generics поправлено по свидетельству
> очевидцев


Прочитал feature matrix, не впечатлило. :)


 
oxffff ©   (2010-09-01 11:37) [31]


> параметрических функций


Параметризованных функций конечно.


 
Anatoly Podgoretsky ©   (2010-09-01 12:49) [32]

> oxffff  (01.09.2010 10:46:10)  [10]

Накликал :-)



Страницы: 1 вся ветка

Текущий архив: 2010.12.12;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.026 c
15-1283776650
12
2010-09-06 16:37
2010.12.12
Что-то не понимаю tDateTime и Variant, раньше работало или путаю?


15-1282803046
xayam
2010-08-26 10:10
2010.12.12
Модераторам/администраторам


2-1285060567
бумбум
2010-09-21 13:16
2010.12.12
Как перехватить события когда форма на переднем плане?


11-1226732009
MTsv DN
2008-11-15 09:53
2010.12.12
Работа с LVItemData


2-1284896319
Первокурсница
2010-09-19 15:38
2010.12.12
Знаки препинания в строке ADOQuery1.SQL.Add( SET ... !!!