Форум: "Прочее";
Текущий архив: 2010.12.12;
Скачать: [xml.tar.bz2];
ВнизСоздание интерфейса без сохранения в переменную Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.003 c