OberonCore https://forum.oberoncore.ru/ |
|
Работа с untagged-типами https://forum.oberoncore.ru/viewtopic.php?f=2&t=35 |
Страница 1 из 1 |
Автор: | sacred [ Понедельник, 28 Ноябрь, 2005 13:21 ] |
Заголовок сообщения: | Работа с untagged-типами |
Неплохо было бы дополнить документацию. Например, нигде не нашёл описания модуля COM, также отсутствуют сведения по квадратным скобкам. В следующем контексте: TYPE LaLa=RECORD [здесь может быть строка, или слово untagged, а может и ещё что нибудь] и далее как обычно. Также они встречаются в описаниях массивов и формальных параметров. Что означают - непонятно. Может, есть ещё какие-то нераскрытые темы. |
Автор: | Илья Ермаков [ Понедельник, 28 Ноябрь, 2005 13:32 ] |
Заголовок сообщения: | |
Не существует такого модуля COM. Это псевдомодуль, compiler-magic, так же, как и SYSTEM. Дает возможность описывать интерфейсы COM, например, указывая GUID в квадратных скобках, как в Дельфе... Про SYSTEM и квадратные скобки можно прочесть в Platform-Specific-Issues (Особенности платформы). Про COM - частично там же. Если же использовать расширенные возможности Direct-To-Com Compiler (в первую очередь полезны для серверов COM) - то это подсистема COM и ее документация, пока что не переведенная. А еще есть подсистема Ctl, содержащая интерфейсы автоматизации к MS Office и кое-какую документацию. На нашем сайте мы ее из дистрибутива вырезали, т.к. она весит добрую половину пакета. Если требуется, закачайте полный ББ на oberon.ch. |
Автор: | sacred [ Понедельник, 28 Ноябрь, 2005 15:56 ] |
Заголовок сообщения: | |
Илья Ермаков писал(а): Не существует такого модуля COM. Это псевдомодуль, compiler-magic, так же, как и SYSTEM. Дает возможность описывать интерфейсы COM, например, указывая GUID в квадратных скобках, как в Дельфе
Вот именно описание псевдомодуля COM больше всего и интересует... Пытаюсь подключаться к OLE-серверам, используя disp-интерфейс. В документации к OLE-серверам имеются только имена свойств иметодов. Вот, например что за функция COM.ID(???) - я её даже использую, но не знаю что она делает. С untagged массивами жуткая проблема. Чтобы вызвать метод WinOleAut.IDispatch.Invoke, необходимо заполнить структуру Код: DISPPARAMS* = RECORD [untagged]
rgvarg*: POINTER TO ARRAY [untagged] OF VARIANTARG; rgdispidNamedArgs*: POINTER TO ARRAY [untagged] OF DISPID; cArgs*: INTEGER; cNamedArgs*: INTEGER; END; Но как распределить память под POINTER TO ARRAY [untagged] OF VARIANTARG - я не понимаю. Процедура NEW - не работает. А что делать??? |
Автор: | Илья Ермаков [ Понедельник, 28 Ноябрь, 2005 18:41 ] |
Заголовок сообщения: | |
Пока с этим не работал. Вообще-то, такие типы выделять можно системными вызовами WinApi.VirtualAlloc или HeapAlloc, как это под Win32 и принято. Может быть, есть где-то функция-оболочка под них. А вообще, Oberon Micrsosystems рекомендует использовать подсистему Com и Direct-To-Com Compiler. Просто до версии 1.5 он не входил в поставку, а продавался отдельно, и приходилось использовать записи с процедурными полями. А подсистема Ctl у Вас есть? |
Автор: | Info21 [ Понедельник, 28 Ноябрь, 2005 19:01 ] |
Заголовок сообщения: | |
sacred писал(а): Но как распределить память под POINTER TO ARRAY [untagged] OF VARIANTARG - я не понимаю. Процедура NEW - не работает. А что делать???
Распределите память под обычный массив нужной длины. Адрес нулевого элемента присвойте своему untagged-указателю. В таком духе. |
Автор: | Сергей Губанов [ Понедельник, 28 Ноябрь, 2005 19:24 ] |
Заголовок сообщения: | |
sacred писал(а): Но как распределить память под POINTER TO ARRAY [untagged] OF VARIANTARG - я не понимаю. Процедура NEW - не работает. А что делать???
Тоже самое на другом форуме http://progz.ru/forum/viewtopic.php?t=20135 |
Автор: | sacred [ Понедельник, 28 Ноябрь, 2005 20:47 ] |
Заголовок сообщения: | |
info21 писал(а): Адрес нулевого элемента присвойте своему untagged-указателю.
В таком духе. А пример можно? Как там будет с совместимостью по присваиванию? И как получить адрес нулевого элемента? Насколько я знаю, функции получения адреса в BlackBox возвращают INTEGER, а не POINTER. |
Автор: | Илья Ермаков [ Понедельник, 28 Ноябрь, 2005 22:08 ] |
Заголовок сообщения: | |
В таких "низкоуровневых" случаях в ББ действительно есть compiler-magic - нетипизированное преобразование SYSTEM.VAL(T - имя типа, к которому приводим, x - значение любого другого типа). Там же в "Особенности платформы" эти вещи описаны. Правильно сказал Trurl на progs.ru - что [untagged] - это чужая память. Распределяется обычно системой. Например, менеджером кучи Windows. |
Автор: | Илья Ермаков [ Понедельник, 28 Ноябрь, 2005 22:12 ] |
Заголовок сообщения: | |
info21 писал(а): Распределите память под обычный массив нужной длины.
Адрес нулевого элемента присвойте своему untagged-указателю. В таком духе. Так делать очень опасно по одной простой причине: если untagged-указатель уйдет "налево" - в другую dll или в системный вызов, то сборщик мусора это не отследит и может прибить объект в самый неподходящий момент. Да даже внутри среды: если все tagged-указатели на память уйдут из области видимости, то память будет освобождена, и untagged-ссылки окажутся висячими! |
Автор: | Info21 [ Понедельник, 28 Ноябрь, 2005 23:40 ] |
Заголовок сообщения: | |
Илья Ермаков писал(а): info21 писал(а): Распределите память под обычный массив нужной длины. Адрес нулевого элемента присвойте своему untagged-указателю. В таком духе. Так делать очень опасно по одной простой причине: если untagged-указатель уйдет "налево" - в другую dll или в системный вызов, то сборщик мусора это не отследит и может прибить объект в самый неподходящий момент. Привяжите объект глобально. |
Автор: | sacred [ Вторник, 29 Ноябрь, 2005 12:08 ] |
Заголовок сообщения: | |
info21 писал(а): Привяжите объект глобально.
Это как? (Извините, что надоедаю....) |
Автор: | sacred [ Вторник, 29 Ноябрь, 2005 12:11 ] |
Заголовок сообщения: | |
Илья Ермаков писал(а): Так делать очень опасно по одной простой причине: если untagged-указатель уйдет "налево" - в другую dll или в системный вызов, то сборщик мусора это не отследит и может прибить объект в самый неподходящий момент. Да даже внутри среды: если все tagged-указатели на память уйдут из области видимости, то память будет освобождена, и untagged-ссылки окажутся висячими!
Очень полезное и информативное замечание! Спасибо, я не знал о таких тонкостях. |
Автор: | Илья Ермаков [ Вторник, 29 Ноябрь, 2005 15:24 ] |
Заголовок сообщения: | |
sacred писал(а): info21 писал(а): Привяжите объект глобально. Это как? (Извините, что надоедаю....) Держать ссылку на память в глобальной переменной. Этакий "якорь". Тогда память не освободится, пока не будет выгружен модуль. Но зачем? [untagged] - это системные объекты, и память под них лучше выделять системно, помимо менеджера памяти ББ. |
Автор: | Takun [ Вторник, 29 Ноябрь, 2005 16:59 ] |
Заголовок сообщения: | |
Еще один вариант объявить Код: TYPE
SomeType = POINTER TO RECORD disPar: DISPARAMS END; а его уже размещать в памяти. |
Автор: | sacred [ Вторник, 29 Ноябрь, 2005 20:35 ] |
Заголовок сообщения: | |
Takun писал(а): Еще один вариант объявить
Код: TYPE SomeType = POINTER TO RECORD disPar: DISPARAMS END; а его уже размещать в памяти. Уверен, что это не сработает. |
Автор: | sacred [ Вторник, 29 Ноябрь, 2005 20:40 ] |
Заголовок сообщения: | |
Илья Ермаков писал(а): В таких "низкоуровневых" случаях в ББ действительно есть compiler-magic - нетипизированное преобразование SYSTEM.VAL(T - имя типа, к которому приводим, x - значение любого другого типа).
спасибо за "наводку", про SYSTEM.VAL - не знал. Однако, это тоже не поможет. Дело в том, что в модуле WinOleAut описание типа выглядит так: Код: DISPPARAMS* = RECORD [untagged] То есть поле rgvarg имеет безымянный тип, который несовместим по присваиванию ни с чем....
rgvarg*: POINTER TO ARRAY [untagged] OF VARIANTARG; ....... Уточняю свой первоначальный вопрос: Можно ли заполнить структуру WinOleAut.DISPPARAMS, не исправляя сам модуль WinOleAut? |
Автор: | sacred [ Вторник, 29 Ноябрь, 2005 21:14 ] |
Заголовок сообщения: | |
Нашёл, как говорится Эврика! Код: VAR
P:WinApi.PtrVoid; Params : WinOleAut.DISPPARAMS; BEGIN P := WinApi.HeapAlloc(WinApi.GetProcessHeap(), {}, SIZE(WinOleAut.VARIANTARG)*n); SYSTEM.PUT(SYSTEM.ADR(Params.rgvarg), P); Params.cArgs := n; ,где n - число параметров вызываемого метода. Всем спасибо за участие. Без вашей помощи я бы долго ковырялся. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |