'Type is not automatable' — не баг ли?

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Re: 'Type is not automatable' — не баг ли?

Сообщение Sergei I. Gorelkin » 09.11.2010 15:21:48

Кажется, наступает некое просветление... Все аргументы с указанием их типов передаются в fpc_dispinvoke_variant, которая с ними разбирается дальше. Уже хорошо, т.к. преобразованиями может заняться RTL.
Для типа WideString передается 8 (varolestr, определена в начале файла rtl/inc/varianth.inc), для типа AnsiString - $48 (varstrarg) (а при обычном присвоении AnsiString->Variant будет тип $100 varstring, почему-то :!: ), для UnicodeString вообще никакого подходящего типа не наблюдается.

Иван Шихалев писал(а):Кстати, насчет «что передается»... А где искать структуру последнего параметра DispInvoke?

Это который Params: Pointer? По смыслу должен указывать на аргументы вызова, которых может быть переменное число, а типы определяются параметром CallDesc.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: 'Type is not automatable' — не баг ли?

Сообщение Иван Шихалев » 09.11.2010 16:07:29

А почему вообще литерал считается UnicodeString? И почему не работает его приведение к AnsiString?
Параметры просто лежат там по порядку?
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Re: 'Type is not automatable' — не баг ли?

Сообщение Sergei I. Gorelkin » 09.11.2010 17:15:27

В винде по идее должно все приводиться к WideString, включая и литералы и ansistring. Что должно быть "не в винде" - без понятия :(
Вообще я раньше почти не соприкасался с предметной областью, так что, возможно, где-то и неправ.
Параметры, наверное, лежат по порядку (а что еще можно придумать?)

Напишу-ка я, пожалуй, в багтрекер все как оно есть на текущий момент...
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: 'Type is not automatable' — не баг ли?

Сообщение Иван Шихалев » 09.11.2010 20:40:04

Еще, кстати, не автоматизируются Int64 и QWord. Интересно, а не нужны ли они в Win64...

Добавлено спустя 2 минуты 10 секунд:
Вообще, на мой взгляд, идеальным решением было бы проверять все эти ограничения только в отдельно включаемом/отключаемом режиме OLE Compatible...
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Re: 'Type is not automatable' — не баг ли?

Сообщение Sergei I. Gorelkin » 09.11.2010 21:18:50

Иван Шихалев писал(а):Еще, кстати, не автоматизируются Int64 и QWord. Интересно, а не нужны ли они в Win64...

Как мне кажется, для выяснения этого вопроса нужно брать что-то типа Platform SDK для Win64 с примерами и смотреть, как там оно работает.

Иван Шихалев писал(а):Вообще, на мой взгляд, идеальным решением было бы проверять все эти ограничения только в отдельно включаемом/отключаемом режиме OLE Compatible...

Для OLE-совместимости вроде бы предназначается тип OleVariant.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: 'Type is not automatable' — не баг ли?

Сообщение Иван Шихалев » 09.11.2010 21:37:20

Sergei I. Gorelkin писал(а):и смотреть, как там оно работает.

Вот здесь — http://msdn.microsoft.com/en-us/library/ms724310%28VS.85%29.aspx — к примеру, long long активно используется.

Sergei I. Gorelkin писал(а):Для OLE-совместимости вроде бы предназначается тип OleVariant.

Тем более непонятно, зачем ограничивать CustomVariant. Правда, есть у меня подозрение, что контролировать совместимость в зависимости от типа может быть не так просто.
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Re: 'Type is not automatable' — не баг ли?

Сообщение Иван Шихалев » 10.11.2010 23:41:18

Sergei I. Gorelkin
А последние изменения в модуле Variants — они какие проблемы призваны решить?
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Re: 'Type is not automatable' — не баг ли?

Сообщение Sergei I. Gorelkin » 11.11.2010 09:44:46

Дык там просто конь не валялся. TCustomVariantType, TInvokeableVariantType не реализованы вообще никак. Вот для начала написал нормальный конструктор и десяток тестов.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: 'Type is not automatable' — не баг ли?

Сообщение Иван Шихалев » 11.11.2010 10:57:39

Про коня верно подмечено. Я щас ковыряю DispInvoke в Invokable... Наверное, к завтрему доковыряю до рабочего состояния.

И еще такой момент: там, ИМХО, DispInvoke в TCustomVariantType, и все кроме DispInvoke в TInvokeableVariantType, надо объявить как abstract, поскольку по сути оно таковым и является. В делфевой версии оно генерит ошибку и больше ничего не делает. На мой взгляд abstract лучше тем, что генерирует кроме run-time error еще и compile-time warning.
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Re: 'Type is not automatable' — не баг ли?

Сообщение Sergei I. Gorelkin » 11.11.2010 11:26:00

Ненене, TCustomVariantType является базой для создания типов Variant, которых просто хранят данные (нет dispatch-методов), делать в нем DispInvoke абстрактным и заставлять всех в обязательном порядке его перекрывать - прямо скажем, не умно. Точно так же с TInvokeableVariantType, в его наследниках не обязательно реализовывать все четыре метода (DoFunction, DoProcedure, GetProperty, SetProperty), достаточно чего-то одного.

Точно так же и с TStream.Read и TStream.Write: реализация по умолчанию, бросающая исключение, позволила вычистить пол-тонны однотипного кода (который к тому же и не должен никогда выполняться!) из всего FCL, где почти все наследники либо только для чтения, либо только для записи.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: 'Type is not automatable' — не баг ли?

Сообщение Иван Шихалев » 11.11.2010 11:32:37

Хм... Пожалуй, соглашусь.

Добавлено спустя 4 минуты 42 секунды:
Да, когда допинаю DispInvoke — куда можно послать патч и в каком виде лучше? (варианты — diff и git diff)
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Re: 'Type is not automatable' — не баг ли?

Сообщение Sergei I. Gorelkin » 11.11.2010 11:58:33

С точки зрения "для протокола и истории" лучше, наверное, в багтрекер. Формат - git diff люди точно присылают, и они успешно применяются, насчет diff так уверенно сказать не могу, но каких-то проблем и с ним быть не должно.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: 'Type is not automatable' — не баг ли?

Сообщение Иван Шихалев » 11.11.2010 12:03:24

ОК. Учитывая, что тестить буду на локальном git-ответвлении...

Добавлено спустя 16 часов 59 минут 43 секунды:
Мда... Со строками вот еще что интересно — соответствие ArgType при автоматизации и vType в вариантном представлении, точнее — несоответствие.

литерал: ArgType = varUnicodeString, vType = varString или varOleStr (в зависимости от того, что в нем)
AnsiString: ArgType = varStrArg, vType = varString
WideString/UnicodeString: ArgType = varUnicodeString, vType = varOleStr
Utf8String: ArgType = varStrArg, vType = varOleStr

Непонятно, как быть с Utf8 vs Ansi...

Добавлено спустя 1 минуту 37 секунд:
Т.е., как я это вижу — Utf8String по хорошему не должна передаваться как varStrArg, а должна как varUnicodeString.

Добавлено спустя 18 часов 5 минут 8 секунд:
http://bugs.freepascal.org/view.php?id=17919
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Re: 'Type is not automatable' — не баг ли?

Сообщение Иван Шихалев » 21.11.2010 04:08:27

Sergei I. Gorelkin
Что-то с последними изменениями (rev. 16389) посыпалась передача всего кроме строк...

Добавлено спустя 6 минут 13 секунд:
Кажется, понял. Теперь сдвиг нужно делать не на sizeof(pointer), а в зависимости от типа... Или все-таки минимум на 4 байта?

Добавлено спустя 4 минуты 53 секунды:
И, кстати, это так задумано, что UnicodeString по значению передается, а по ссылке — нет?
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Re: 'Type is not automatable' — не баг ли?

Сообщение Sergei I. Gorelkin » 21.11.2010 06:17:09

Попробую по порядку:
- В генерации сдвига в компиляторе был тупой баг, считалось что все передается по ссылке и под каждый аргумент отводилось sizeof(pointer) байт, хотя double передавался по значению и для него нужно sizeof(double). Из-за этого на x86_64, собственно, все было хорошо, а на i386 твой патч не работал. Это я поправил в ревизии 16350.
- Потом в ревизии 16360 я в добавил проверки в парсинг dispinterface, чтобы в них можно было использовать только automatable типы. Заодно убрал ограничения времен windows 95 на перечисляемые типы, и решил проблему не-передачи перечисляемых типов по ссылке. Т.к. вызовы методов variant полностью динамические и для них нет объявлений с указанием как что передавать, то используется следующая логика: если можно передать по ссылке, то передаем по ссылке, иначе по значению. А по ссылке можно передавать все, кроме результата вызова другой функции, свойств и непосредственно заданных значений.
- Затем нужно было забороть тип variant, который всегда передавался по ссылке. Что и было сделано в 16389. В параметрах по-прежнему передается ссылка, но бит $80 устанавливается не всегда. Из-за этого в патч для DispInvoke придется вносить изменения, аналогичные тем, что внесены в winunits-base/src/comobj.pp ревизии 16388. Но это я и сам могу сделать.

Теперь эта UnicodeString, будь она неладна. Ее я даже еще не начинал копать. Но уже понятно, что с ней надо обходиться примерно так, как с AnsiString. Откуда растут ноги у varString и varStrArg? varString=$100, т.е. находится в диапазоне "псевдо-пользовательских" типов. "Псевдо" - потому что настоящий TCustomVariant начинается с $10F. А находится в этом диапазоне потому, что это специфичный для Delphi/FPC тип, и COM с ним работать просто не умеет.
А varStrArg используется только для передачи типа AnsiString в DispInvoke, потому что в CallDesc на каждый аргумент отводится только 1 байт, и varString в него просто не помещается.
Т.е, действуя по образу и подобию, нужно изменять varUnicodeString на $102 (кстати в последних Delphi оно так и есть, только имя varUString), добавлять какой-нибудь varUStrArg=73, и дальше по аналогии...

Что с этой радостью делать в самой процедуре DispInvoke - тоже непонятно. Просто так подставлять varOleStr вместо varUnicodeString нельзя, это разные типы, нужно выделять память с помощью SysAllocateString и копировать строку туда, но это возможно только для windows...
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Пред.След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru