|
Внешняя обработка в управляемых формах. | ☑ | ||
---|---|---|---|---|
0
Torquader
12.05.15
✎
21:58
|
Получается, что модуль внешней обработки компилируется каждый раз когда с клиента на сервер прилетает команда ?
То есть на сервере от внешней обработки не хранится вообще ничего ? Просто вставил в конец модуля "Сообщить" и оно вызывается при каждом вызове сервера. В общем, ощущение что всю систему проектировал какой-то криворукий гоблин. |
|||
1
ДенисЧ
12.05.15
✎
22:01
|
Не гоблин, а укуренный инопланетянин.
|
|||
2
Fragster
гуру
12.05.15
✎
22:01
|
а не во внешней не так?
|
|||
3
Fragster
гуру
12.05.15
✎
22:02
|
но вообще да - вместо того, чтобы держать контекст на сервере и с клиента слать сообщения сделали гомункула
|
|||
4
Torquader
12.05.15
✎
22:07
|
Я просто очень долго пытался понять, почему реквизиты обработки теряются при каждом вызове, а потом оказалось, что теряется вообще всё.
Вопрос - зачем тогда нужны реквизиты у обработки, если они есть только в процессе вызова. А также, получается, что при каждом вызове всё гоняется туда-обратно. |
|||
5
Torquader
12.05.15
✎
22:10
|
(1) Укуренных инопланетян я видел, они на такое не способны.
А это, как говорится, многоруккий шивва нижними руками, которые аккурат из того места растут, из которого не надо. P.S. была хорошая идея, как можно всё сделать, и оказалось, что тут, в принципе, ничего сделать нельзя, так как для каждого вызова компиллять модуль !!! Хотя, видимо, писал специалист по php, так как там всё именно так и работает. |
|||
6
Torquader
12.05.15
✎
22:14
|
И, я так понимаю, что со всеми остальными модулями происходит тоже самое, кроме модулей с повторным использованием, где что-то сохраняется в кеше.
|
|||
7
Torquader
13.05.15
✎
00:03
|
Просто, когда у одной обработки две формы и обе открыты, то в каждой форме свой набор реквизитов обработки и они между собой никак не связаны.
Реально же получается, что реквизиты и табличные части обработки ни чем не отличаются от реквизитов формы, кроме сложностей с доступом к ним (приходится получать объект обработки из реквизита). |
|||
8
Asmody
13.05.15
✎
00:09
|
В первый раз услышали про stateless application?
|
|||
9
Torquader
13.05.15
✎
00:12
|
(8) Я прекрасно знал, что объекты хранятся только на клиенте.
Но для меня новым оказалось, что серверная часть модуля формы перекомпилляется при каждом вызове сервера, а также что при открытии одной формы обработки из другой данные реквизитов обработки не передаются - ведь команда открытия выполняется сначала на клиенте из формы, в которой эти реквизиты заполнены. |
|||
10
Asmody
13.05.15
✎
00:14
|
[Я прекрасно знал, что объекты хранятся только на клиенте.] — о как! А для меня это откровение.
|
|||
11
Asmody
13.05.15
✎
00:15
|
РеквизитФормыВЗначение(), ДанныеФормыВЗначение() зачем-то ведь придуманы, а?
|
|||
12
Torquader
13.05.15
✎
00:16
|
(10) А где им ещё быть - данные хранятся в базе, когда что-то из базы открывается, сервер приложений считывает данные, готовит форму и отправляет всё это на клиента, после чего у него "случается амнезия" и он всё забывает.
|
|||
13
Torquader
13.05.15
✎
00:17
|
(11) Попробуй эти функции вызвать без контекста ?
А контекст - это то, что приехало к серверному вызову с клиента - и все наши данные именно в контексте. |
|||
14
Asmody
13.05.15
✎
00:17
|
(12) Это не объекты, это представление объектов.
|
|||
15
Asmody
13.05.15
✎
00:18
|
Проблема-то в чем? Вызвать другую форму этого же экземпляра обработки?
|
|||
16
Torquader
13.05.15
✎
00:20
|
(15) Проблема в том, что при заполнении реквизитов объекта (не формы) в одной форме обработки другая форма видит старые значения (так как они внутри её контекста живут).
|
|||
17
hhhh
13.05.15
✎
00:23
|
(16) то, что Сообщить вызывается 2 раза, ведь не означает, что компилируется 2 раза.
|
|||
18
Torquader
13.05.15
✎
00:23
|
На сервере экземпляр обработки получается через Обр=РеквизитФормыВЗначение("Объект") и в этот момент компилляется модуль обработки.
|
|||
19
Asmody
13.05.15
✎
00:25
|
(18) Он не компилируется, а исполняется.
|
|||
20
Torquader
13.05.15
✎
00:25
|
(17) Сообщить в скобках сервера (#Если Сервер) вызывается при каждом вызове серверной процедуры.
Сообщить в конце модуля формы вызывается в момент получения объекта обработки из реквизита. Я то думал, что модуль обработки компилляется один раз при её загрузке. |
|||
21
Asmody
13.05.15
✎
00:25
|
Потому что создается новый объект типа "Обработка"
|
|||
22
Torquader
13.05.15
✎
00:27
|
(19) Как бы этот процесс не назывался - из текста модуля (скорей всего из оптимизированного двоичного представления) собирается список функций и процедур, которые в этом модуле есть.
(21) Правильно, для обслуживания нашего вызова создаётся объект "Обработка", который после выполнения нашего вызова будет разрушен. |
|||
23
Asmody
13.05.15
✎
00:29
|
(22) Он уже собран. Считай, что выполняется конструктор объекта.
|
|||
24
Asmody
13.05.15
✎
00:30
|
Почитай где-нибудб про immutable-объекты и прими как данность, что они в 1С есть.
|
|||
25
Asmody
13.05.15
✎
00:30
|
не на 100% конечно, но хоть как-то
|
|||
26
Torquader
13.05.15
✎
00:33
|
(23) Очень сложно проверить, что происходит на самом деле, так как выполнение части модуля ниже всех функций можно организовать и без повторной компиляции самого модуля, но, так как модуль нигде не хранится, то можно предположить, что он компилляется ещё раз.
|
|||
27
Torquader
13.05.15
✎
00:42
|
(24) Получается, что объектов вообще нет - есть только имитация их существования.
Неизменяемый объект - как раз и предполагает, что он может быть один для нескольких клиентов - в 1С же мы наблюдаем, наоборот, несколько объектов для одного клиента. |
|||
28
Asmody
13.05.15
✎
00:43
|
(26) Я полагаю, что компилируется он в момент открытия. И больше файл не перечитывается. После чего "класс" обработки занимает свое место в памяти "виртуальной машины 1С" и выполняется в нужный момент.
|
|||
29
Torquader
13.05.15
✎
00:44
|
И потом, если при каждом обращении к объекту, как ты говоришь в (23) вызывается конструктор - это же не говорит, что объект неизменяемый, а как раз подтверждает тот факт, что его создают только тогда, когда он нужен.
|
|||
30
H A D G E H O G s
13.05.15
✎
00:45
|
(0) Да может просто тупо так сделали просто ради того, чтобы было.
|
|||
31
Torquader
13.05.15
✎
00:45
|
(28) На этот вопрос очень сложно ответить, так как кеш, скорей всего, хранит не скомпилированный модуль, а данные для его компилляции - так проще - кешировать то, что получается с сервера базы данных.
|
|||
32
Asmody
13.05.15
✎
00:45
|
(27) Да нет же. Два контекста не могут сделать один объект. Или наоборот, один объект не может принадлежать двум контекстам.
|
|||
33
Asmody
13.05.15
✎
00:47
|
(29) а я и не говорю, что он неизменяемый. Я говорю, что к нему надо относиться как будто он неизменяемый. Еще и стейтлесс.
|
|||
34
Torquader
13.05.15
✎
00:47
|
(32) Ну да, есть объекты, называемые "Контекст" и он у каждой формы свой.
А наличие кластера серверов как раз и подтверждает тот факт, что никто модуль в памяти не хранит - ведь следующий запрос от нашей формы может уйти другому обработчику, который ещё даже и не знает, что мы форму открыли. |
|||
35
Asmody
13.05.15
✎
00:49
|
(31) при чем тут кеш? Речь про устройство "исполнителя 1С". Я не думаю, что оно принципиально отличается от JVM или другой VM.
|
|||
36
H A D G E H O G s
13.05.15
✎
00:50
|
(34) Сеансовые данные мигрируют.... через файл.
|
|||
37
Asmody
13.05.15
✎
00:50
|
(34) во, ты уже начал понимать, почему у форм не может быть состояния на сервере
|
|||
38
Torquader
13.05.15
✎
00:51
|
(35) Он реально отличается - хотя бы тем, что их два - на клиенте и на сервере, и тот, который на сервере умеет забывать всё сразу после окончания обработки вызова.
|
|||
39
Torquader
13.05.15
✎
00:52
|
(37) Я прекрасно знал, что у форм нет состояния на сервере, так как сервер вообще не знает, что происходит с формой.
Но для меня очень удивительным оказалось, что две формы на клиенте не могут иметь общих данных. |
|||
40
Torquader
13.05.15
✎
00:54
|
(36) Ну это ты про Параметры сеанса - так они и в базе данных могут хранится.
|
|||
41
Asmody
13.05.15
✎
00:54
|
(38) Можно считать, что ВМ на сервере и клиенте различные. Это не принципиально. В случае с веб исполнитель вообще javascript браузера.
|
|||
42
Asmody
13.05.15
✎
00:55
|
(39) так если у них нет состояния, как у них могут быть какие-то общие данные?
|
|||
43
Torquader
13.05.15
✎
00:56
|
Просто у Microsoft в его реализации COM-объектов объекты прекрасно живут на разных машинах и обмениваются данными, независимо от расположения, и всё работает.
|
|||
44
H A D G E H O G s
13.05.15
✎
00:57
|
(40) Нет. Они хранятся в файлике на сервере 1С.
|
|||
45
Torquader
13.05.15
✎
00:58
|
(42) Их вообще просто нет.
Объект на сервере собирается по данным, переданным с клиента, а они живут в контексте формы. |
|||
46
Torquader
13.05.15
✎
00:59
|
(44) Ну, сеансы в php тоже обычно хранятся в файликах, и несколько процессов прекрасно их между собой делят - тут создатели 1С подсмотрели готовое решение.
|
|||
47
Asmody
13.05.15
✎
08:38
|
(46) Сессии в php (и не только в php) могут храниться разными способами. Можно не пользовался встроенными и реализавать свой.
В общем случае сессия - это некий persistent-объект, в котором что-то хранится, и id которого передается при каждом вызове (обычно в куках, но необязательно). |
|||
48
ЧеловекДуши
13.05.15
✎
08:55
|
Странно все это. Ну да УФ при вызове &НаСервере, каждый раз все что делалось на Клиенте переносит на сервер.
Таки хочется спросить, у ТС: Пиши с этим учетом, забудь про Толстый клиент и что все держалось в форме. Коль тебе на сервер надо перекидывать какую либо Таблицу значений из реквизитов формы. То трансформируй её в Структуру и обращайся к процедуре формы "БезКонтекста". Старайся меньше использовать обращений к процедурам "НаСервере" :) |
|||
49
ЧеловекДуши
13.05.15
✎
08:56
|
+(48) Используй Временное Хранилище значений :)
|
|||
50
Torquader
13.05.15
✎
09:20
|
(48) Да, в общем-то, проблем с переносом нет.
Об=РеквизитФормыВЗначение("Объект");// получаем объект // здесь что-то делаем с объектом ЗначениеВРеквизитФормы(Об,"Объект");// возвращаем его назад Просто, из одной формы в другую приходится передавать все данные объекта обработки вручную. Кстати, таблица значений прекрасно живёт в реквизитах формы, если она нужна на клиенте. Другое дело, что когда в таблицу загрузил половину базы для проведения обработки над ней - каждый серверный вызов сразу показывает всю глупость идеи управляемых форм, так как нет возможности выбора передаваемых на сервер данных. |
|||
51
asady
13.05.15
✎
09:36
|
(50) просто вдруг выясняется что управляемые формы не для таких задач
для таких задач придется юзать регламентое задание и выполнять всё только на сервере - а в УФ только настройки этого задания менять и логи просматривать |
|||
52
Torquader
13.05.15
✎
09:41
|
(51) Если бы к данным регламентного задания можно было иметь доступ в момент его исполнения - тогда да.
А так - как ни крути - ничего хорошего не выйдет. Потому как, если что-то обрабатывается, то пользователю придётся показывать результат, а это форма. |
|||
53
asady
13.05.15
✎
09:43
|
(52) что мешает писать логи в РС регламентному заданию?
а твоей обработке читать этот РС и показывать состояние хода выполнения? |
|||
54
Torquader
13.05.15
✎
09:47
|
(53) Если я что-то сохраняю в базе, то ничего не мешает и просто вызывать функции "НаСервереБезКонтекста" и работать с этими сохранёнными данными.
К сожалению, не всё можно просто и удобно сохранить в данных. Например, любой объект (то есть не ссылку, а сам объект с данными) сохранить не получится - его придётся каждый раз создавать заново. То, что объект может прекрасно жить в памяти модуля, исполняющего фоновое задание, не значит, что его можно увидеть пользователю. Просто, некоторые простые вещи, которые во многих системах реализуются "из коробки" в 1С требуют очень больших танцев с бубном, и отрицательно сказываются на производительности. |
|||
55
asady
13.05.15
✎
09:56
|
(54) ты просто ещё не вкурил новую философия от 1С - тебе надо раздуплиться - это бывает сложно
Конечно задача которая в толстом клиенте решается просто теперь может потребовать разработку нового алгоритма, что раздражает и хочется сказать "УФ=УГ" - но наверное стоит присмотреться к новой философии 1С, тем более эта философия совсем не нова. |
|||
56
Goggy
13.05.15
✎
09:58
|
(55) Заинтриговал. И в чём же её суть? :)
|
|||
57
Asmody
13.05.15
✎
10:01
|
Из всего вышесказанного становится понятна рекомендация 1С не делать сильно нагруженных УФ.
|
|||
58
fisher
13.05.15
✎
10:06
|
(4) Это да. Для меня тоже в своё время стало открытием, что реквизиты отчетов/обработок в УФ превратились в атавизм, т.к. не являются частью сериализуемого контекста.
Честно говоря, я совсем не уверен, что выбрав stateless-модель, 1С пошла по правильному пути. Хотя, учитывая сколько боков даже в этой модели у них вылазит, может и правильно. |
|||
59
Asmody
13.05.15
✎
10:08
|
(58) stateful в кластере и в вебе чревато еще большими косяками
|
|||
60
fisher
13.05.15
✎
10:16
|
(59) Ну как бы да, с одной стороны. С другой - профит тоже есть. И потом - какой, нафиг, stateless, если состояние таки на сервере хранится? Контекст сеанса, данные форм на сервере таки удерживаются и синхронизируются с клиентом. Чего уж тут мелочиться? Можно было бы и объекты удерживать.
|
|||
61
Torquader
13.05.15
✎
10:43
|
(58) Они сериализуемы, только вручную - то есть как раз реквизиты-то и живут в контексте, а вот самого объекта там нет, когда мы его создаём, то мы создаём его копию по данным контекста, и если данные в контекст вернуть, то всё будет прекрасно.
Вопрос же был в том, почему при открытии одной формы обработки из другой данные объекта обработки не передаются, особенно, если учитывать, что открытие вызывается с клиента. |
|||
62
Torquader
13.05.15
✎
10:47
|
(59) В нормальном кластере можно держать данные клиента на сервере, пока не порвётся соединение, просто тогда каждая часть кластера знает, каких клиентов она обслуживает и гонять весь набор данных от клиента к серверу и обратно можно только в момент перехода на другой участок кластера.
А когда при каждом вызове никто не знает, кто будет исполнять серверный код - это создание проблем на пустом месте. Не забываем, также, что когда мы помещаем OLE-объект в хранилище значения, а потом это хранилище кладём в базу, то сам объект остаётся жить только в том исполнителе, где он был создан, и, если следующий участок нашего кода будет исполняться на другом участке, то объект будет разрушен, а, скорей всего, мы получим нестыковку "Заглушки" и основного объекта, что иногда кончается крахом всей подсистемы OLE и аварйным завершением процесса его вызвавшего. |
|||
63
Asmody
13.05.15
✎
10:51
|
(62) [тогда каждая часть кластера знает, каких клиентов она обслуживает] — а теперь представим ситуацию, когда эта часть кластера падает. И что должно произойти?
|
|||
64
Asmody
13.05.15
✎
10:52
|
Про OLE-объекты вообще лучше забыть и не использовать этот атавизм.
|
|||
65
Torquader
13.05.15
✎
10:53
|
Короче, как я и сказал в (50) объекта "Обработка" просто вообще нет. Когда мы выполняем РеквизитФормыВЗначение("Объект") у нас создаётся объект "Обработка" по тем данным, которые были сохранены в форме (а там живут его реквизиты).
Можно считать, что вызывается конструктор с параметрами. Теперь мы можем работать с нашим объектом. Потом, когда мы закончиили работу, мы его должны сохранить в реквизит, чтобы данные реквизитов ему соответствовали. То есть выполняем ЗначениеВРеквизитФормы. В следующий раз, когда мы снова создаём объект, он создаётся в том состоянии, в котором мы его сохранили в реквизит. В общем - как сериализация в php - прочитал, поработал - не забудь сохранить. |
|||
66
Torquader
13.05.15
✎
10:54
|
(63) Если часть кластера упала, то клиенты должны переходить на другую часть, собственно именно тогда и переходить, а не каждый раз.
|
|||
67
Asmody
13.05.15
✎
10:55
|
(66) А что делать с данными клиента, которые "держал" этот кусок кластера?
|
|||
68
Torquader
13.05.15
✎
11:00
|
(64) Это не атавизм, это целая идеология программирования.
И от них никуда не денешься, так как эта реализация обеспечивает передачу данных между исполнителями независимо от среды. А по сути, это всего-лишь некоторая удобная надстройка над механизмом удалённого исполнения. И потом, сами интерфейсы COM-объектов это всего лишь набор некоторых стандартных таблиц функций, которые система умеет передавать. |
|||
69
Torquader
13.05.15
✎
11:06
|
(67) Загрузить с клиента.
Никто же не говорит, что данные хранятся только на сервере - они должны быть и на сервере и на клиенте, только не надо все данные каждый раз передавать туда и обратно. А смена исполнителя - это как раз тот момент, когда можно передать данные с клиента на сервер. При этом, конечно, потеряются данные последнего исполнения, если на них упал участок, но, насколько я понимаю, если в 1С участок падает на исполнении, то клиент закрывается с ошибкой, так что ничего нового они не изобрели. |
|||
70
Torquader
13.05.15
✎
11:09
|
На самом деле, в Web-программировании именно так и было - все данные хранились на клиенте и при каждом обращении к серверу передавались на сервер, а потом обратно на клиента с новой версией страницы.
Потом появился ajax, когда программист выбирает, какие данные ему нужно отправить на сервер и что получить в ответ, не обновляя форму целиком. А 1С у нас, на данный момент, на первом этапе. (Хотя, вызовы "БезКонтекста" есть, но нет возможности собрать кастомизированный контекст). |
|||
71
Asmody
13.05.15
✎
11:16
|
(68) Это атавизм хотя бы по той причине, что с кроссплатформенностью у COM всё плохо. Да и сама Microsoft почти похоронила эту технологию.
|
|||
72
Asmody
13.05.15
✎
11:18
|
(70) ajax не предусматривает stateful бекенда. А даже наоборот, потенциально позволяет разбить бекенд на кучу относительно независимых микросервисов.
|
|||
73
fisher
13.05.15
✎
11:21
|
(70) Почему на первом? 1С упирает на то, что они стараются гонять не все данные, а только изменения. Правда, типа не всегда это возможно. Контекст формы кастомизируется как угодно.
(71) Ок. Какие альтернативы для доступа к внешним библиотекам из скриптовых языков? |
|||
74
Asmody
13.05.15
✎
11:22
|
(73) В мире *nix как-то выходят из положения.
|
|||
75
fisher
13.05.15
✎
11:24
|
(74) Как? Консольными утилитами?
|
|||
76
Asmody
13.05.15
✎
11:24
|
(75) Я бы сказал — успешно.
|
|||
77
fisher
13.05.15
✎
11:26
|
(76) Ручным плугом пахать тоже вполне успешно получается.
|
|||
78
Torquader
13.05.15
✎
11:31
|
(74) Ну, выходят потоками - просто для передачи потока данных как-то нужно договариваться, что там передаётся, как раз COM-подсистема и являлась тем звеном, которое скрывало от пользователя механизм договорённости.
В глубине COM-механизма лежат или WM_COPYDATA или тот же TCP-тунель, а внутри одного процесса допустимы и прямые вызовы. Главной отличительной особенностью от всего остального является механизм разделения объектов, когда сам объект остаётся на месте, а передаётся только его интерфейс, который как раз и есть stateless. (73) Обратно, может быть, и летят только изменения, а вот туда, всё, что есть, так как сервер-то не знает, что ему будет нужно, особенно, если модуль будет собираться уже после прихода данных. |
|||
79
Torquader
13.05.15
✎
11:34
|
И, на самом деле, никто не мешает реализовать идеологию COM в Linux-системе, так как требуется реализация нескольких базовых классов, отвечающих за передачу данных.
Собственно говоря, Web-сервис, можно рассматривать как interface, и тогда все данные, которые передаются к нему и от него - это вызовы методов этого интерфейса. (Не забываем самую главную особенность интерфейсов - у них есть только методы, а все данные живут в основном объекте). |
|||
80
H A D G E H O G s
13.05.15
✎
11:36
|
(71) Можно про похороны COM технологии Microsoft-ом подробнее?
А то разработчики ЯП в опасносте. |
|||
81
H A D G E H O G s
13.05.15
✎
11:37
|
(68) OLE - это не COM.
1С не работает с OLE от слова "вообще". |
|||
82
Torquader
13.05.15
✎
11:38
|
(77) Да всё там нормально, просто там костыли другой системы.
Передачи данных напрямую от одного процесса другому нет ни там ни там. Проецирование файла в память, которое продвигает Microsoft, всё равно остаётся файлом на диске, а в Linux можно сделать виртуальный файл, когда каждая запись будет сопровождаться функцией получения данных с другой стороны. |
|||
83
Torquader
13.05.15
✎
11:40
|
(81) OLE - это надстройка над COM-подсистемой для организации общего интерфейса для пользователя.
Собственно говоря, для OLE нужны несколько классов, определённых в COM и реализация как со стороны клиента, так и со стороны сервера. 1С с OLE прекрасно работает, когда мы кидаем файл на форму приложения 1С, со стороны 1С вызываются методы для получения файла. |
|||
84
Torquader
13.05.15
✎
11:41
|
Только не стоит забывать, что OLE до сих пор требует однопоточное окружение, тогда как в общей модели COM есть и многопоточные и даже потоконезависимые.
|
|||
85
H A D G E H O G s
13.05.15
✎
11:41
|
Microsoft все ширше и ширше продвигает COM из всех сил.
|
|||
86
H A D G E H O G s
13.05.15
✎
11:43
|
(83) Не стоит путать OLE с ActiveX. OLE - это прообраз ActiveX, работал только внутри продуктов MS Office и позже мутировал в ActiveX.
|
|||
87
Torquader
13.05.15
✎
11:43
|
(85) На самом деле, java-классы можно рассматривать как некоторое подобие COM механизма.
|
|||
88
Torquader
13.05.15
✎
11:45
|
(86) Наоборот ActiveX это часть OLE, так как ActiveX это реализация интерфейса IDispatch, который для OLE и не нужен.
OLE - это возможность внедрения и интеграции одного объекта в другом. |
|||
89
H A D G E H O G s
13.05.15
✎
11:48
|
(87) Нет.
Я вооот про это: https://msdn.microsoft.com/en-us/library/windows/desktop/dd316908(v=vs.85).aspx Microsoft говорит - используйте интерфейсы, а не экспортные функции DLL. Это началось с MS VISTA. Все это поддерживается COM - механизмами, ибо будь иначе (без COM) - Microsoft бы как минимум дала бы CLSID для создания фабрик классов вручную. Да и ручное создание фабрик классов требует работы с указателями - что запрещено в "рассово" верных языках. |
|||
90
H A D G E H O G s
13.05.15
✎
11:50
|
(88) IDispatch для OLE тоже нужен.
|
|||
91
Torquader
13.05.15
✎
11:50
|
(89) Это ещё началось с Windows NT, когда было придумано так называемое "позднее связывание", когда мы не знаем самого объекта, а знаем только о его интерфейсах.
|
|||
92
H A D G E H O G s
13.05.15
✎
11:51
|
(91) Охохох... Я про козу, он - про ерему.
|
|||
93
Torquader
13.05.15
✎
11:51
|
(90) Для внедрения или соединения объектов IDispatch не нужен, он будет нужен, когда мы заходим из приложения-владельца что-то с объектом сделать.
|
|||
94
Torquader
13.05.15
✎
11:53
|
(92) Просто, подключение и вызов функции из DLL напрямую требуют имени DLL, её размещения и имени функции в DLL. Для COM-объекта же требуется только его GUID (точнее CLSID), что позволяет использовать разные версии объектов в одном приложении, что с DLL достаточно сложно.
|
|||
95
H A D G E H O G s
13.05.15
✎
11:53
|
(91) Я знаю, что такое интерфейсы.
Я говорю, что до ms vista WinAPI был реализован в виде экспортных функций dll-ок. Когда появился Vista - весь новый функционал WINAPI стал реализовываться через COM. |
|||
96
H A D G E H O G s
13.05.15
✎
11:54
|
(94) Ну и версионирование - тоже как плюс к COM.
|
|||
97
H A D G E H O G s
13.05.15
✎
11:55
|
(94) Ну вообще для COM объекта требуется только PROGID.
|
|||
98
Torquader
13.05.15
✎
11:56
|
(95) На самом деле, сначала был некоторый базовый WinAPI, потом, с появлением Windows 2000 в нём появились функции с добавкой Ex, которые его немного расширили. Видимо, вторую добавку никто делать не захотел.
|
|||
99
Torquader
13.05.15
✎
11:57
|
(97) ProgId это всего лишь способ отыскания ClassId, особенно, если посмотреть, что живёт в реестре в разделе ProgId.
|
|||
100
H A D G E H O G s
13.05.15
✎
12:02
|
(94) COM технология - это всего лишь:
1) Автоматическая загрузка DLL по хранимому пути в реестре. 2) Создание фабрики класса по хранимому CLSID в реестре. 3) Создание объекта и возврат его интерфейса. Все это делается Windows автоматом просто по одному вызову CoCreateInstance() Но! Ты можешь отказаться от этого (от COM) и самостоятельно загрузить dll, создать фабрику классов через DllGetClassObject() и создать экземпляр класса. Для этого бы должен знать (и хранить): 1) Путь к библиотеке. 2) CLSID требуемого объекта. 3) CLSID фабрики классов (она фиксирована, ничего страшного) 4) Среда разработки умеет работать с указателями. Гемморой. |
|||
101
Torquader
13.05.15
✎
12:03
|
Самое главное, что новый WinAPI требует новых сообщений, а их количество ограничено, поэтому, всё сводится к использованию WM_COPYDATA, а интерфейсы - это всего лишь механизм.
Опять же, один COM-сервер может прекрасно обслуживать все программы, тогда как DLL в каждый процесс будет внедряться своя. Да и потом, директория WinSxS и всё, что с ней связано, объясняют, что с количеством Dll все просто запутались. |
|||
102
H A D G E H O G s
13.05.15
✎
12:04
|
(99) CLSID и пути к dll. это 2 важных параметра. Ну и еще наличие библиотеки типов.
|
|||
103
Torquader
13.05.15
✎
12:05
|
(102) Во-первых, можно создать объект без библиотеки типов - он прекрасно работает и ничего лишнего не требует, просто использующая его сторона не может ничего узнать о том, какие методы этот объект поддерживает.
|
|||
104
H A D G E H O G s
13.05.15
✎
12:06
|
(103) Про библиотеку типов - просто к слову. Я знаю, что такое библиотека типов.
Давай, чтобы не возникало вопросов, я скину тебе поделку свою. |
|||
105
Torquader
13.05.15
✎
12:07
|
(100) Ну, просто можно самому заглянуть в реестр и найти там данные, система же их именно там и ищет.
Поскольку я на Си (а не Си++) писал COM-сервера, то я прекрасно знаю, что и где делает система, чтобы найти объект. |
|||
106
Torquader
13.05.15
✎
12:08
|
(104) Библиотека типов интересна, когда ты описываешь свои структуры для передачи данных - просто реализация IMarshal будет немного сложнее, чем описание типа.
|
|||
107
H A D G E H O G s
13.05.15
✎
12:08
|
(105) Можно и заглянуть. А можно вообще с реестром не работать.
|
|||
108
H A D G E H O G s
13.05.15
✎
12:10
|
(105) Все можно вытянуть из библиотеки типов, даже не занося данные о dll в реестр. Если разработчик потрудился написать эту бблиотеку типов.
|
|||
109
Torquader
13.05.15
✎
12:10
|
(107) Ну, когда нужно загрузить объект, которого нет в реестре, то приходится это делать вручную, повторяя то, что делает система.
Причём, иногда можно создать объект и "подсунуть" его системе перед тем, как его получит другое приложение, стремящееся создать то, чего в реестре нет. |
|||
110
H A D G E H O G s
13.05.15
✎
12:11
|
(109) Да, ты чертовски прав.
Вот и моя Нетленка так делает :-) |
|||
111
Torquader
13.05.15
✎
12:12
|
(108) Ну не всё, а просто получить ITypeInfo потом ITypeLib и дальше просто вызывать его методы.
То есть все слова о том, что есть Библиотека типов сводятся к реализации интерфейса ITypeLib. |
|||
112
fisher
13.05.15
✎
12:12
|
(82) Что именно нормально? Я не настоящий сварщик. Какие в линуксе есть способы работать из скрипта с внешней библиотекой, кроме как через потоки ввода/вывода? А для этого нужна утилита, которая будет уметь эту библиотеку в потоки ввода/вывода.
|
|||
113
Torquader
13.05.15
✎
12:15
|
(112) Здрастьте, приехали, а в Linux script, насколько я помню, на языке shell выполняется, и там можно только команды системы использовать.
Не забываем, что WScript.exe, на котором в Windows пишут сценарии, это всего лишь одна из реализаций некоторого вспомогательного объекта. В Linux для таких объектов есть язык Си, так как gcc компиллятор всегда в наличии. |
|||
114
H A D G E H O G s
13.05.15
✎
12:15
|
(111) Я те скинул на почту, зацени.
|
|||
115
Torquader
13.05.15
✎
12:15
|
(110) Просто, когда нужно было загрузить две версии одного и того же объекта (из разных Dll, но с одним кодом версии), то приходилось делать именно это.
|
|||
116
fisher
13.05.15
✎
12:17
|
(113) Кроме капитанских обрывков информации внятный ответ есть? Типа "нет, нету". Или "есть вот такой".
|
|||
117
Torquader
13.05.15
✎
12:17
|
(114) Посмотрю, конечно.
Просто, на самом деле, в Windows есть ключ в реестре для общих объектов, а есть ключ пользователя, где точно также можно регистрировать объекты, которые будут создаваться по ProgId, но только в сеансе того пользователя, в котором они зарегистрированы. |
|||
118
H A D G E H O G s
13.05.15
✎
12:18
|
(117) Да, я в курсе :-)
|
|||
119
Torquader
13.05.15
✎
12:18
|
(116) В Linux вообще нет сценариев, где можно работать с объектами, в shell сценариях переменные хранят только строки.
Так что только командная строка. |
|||
120
H A D G E H O G s
13.05.15
✎
12:19
|
(117) Правильные разработчики ВК в dllRegserver сначало пытаются писать в общий раздел, а если нет прав - в частный.
|
|||
121
fisher
13.05.15
✎
12:20
|
(119) Ну вот. Я и говорил о том, что с COM там сравнивать тупо нечего. А ты - "нормально там всё".
|
|||
122
Torquader
13.05.15
✎
12:20
|
(118) Ты-то в курсе, а куча горе писателей COM-объектов - нет, вот и приходится запускать RegSvr32 под администратором, чтобы вписать объект в систему.
Если внимательно читать документацию Microsoft, то можно понять, что они-то как раз подумали обо всём, но большинство производителей программ глубоко ничего не читали, вот и получается, что из-за совместимости у пользователя должны быть права администратора. |
|||
123
Torquader
13.05.15
✎
12:22
|
(121) Чем тебя не устраивает, скажем php и его модули.
Не забываем, что в php, например, можно параллельные потоки запускать, что в Windows сценариях и не снилось. А вы COM. Под зад пинком этот COM, если предлагается многопоточность из коробки. |
|||
124
Torquader
13.05.15
✎
12:25
|
(120) В Windows также есть файл .manifest,
https://msdn.microsoft.com/ru-ru/library/1w45z383(v=vs.110).aspx где можно описать вызываемые из кода объекты и их положение в dll, и система, прежде чем искать в реестре, будет искать в этих файлах. Так что, вполне вероятно, что некоторые проблемы с использованием COM-объектов можно решить просто написанием этого файла (я, правда, не пробовал). |
|||
125
H A D G E H O G s
13.05.15
✎
12:27
|
(124) Это работает для функции LoadLibraryEx
|
|||
126
Torquader
13.05.15
✎
12:31
|
(125) А для GetClassObject нет ?
|
|||
127
Torquader
13.05.15
✎
12:33
|
Ладно, на досуге (если таковой будет) проверю, что можно хранить в manifest и как это позволяет обходить проблемы с регистрацией объектов.
|
|||
128
H A D G E H O G s
13.05.15
✎
12:35
|
(126) Она использует в своей работе
coLoadLibrary() в которой нет флага поиска пути. https://msdn.microsoft.com/en-us/library/ms886346.aspx |
|||
129
H A D G E H O G s
13.05.15
✎
12:36
|
(128) Почему то меня поиск вынес на win ce, но я думаю, в обычных виндах - также.
|
|||
130
Asmody
13.05.15
✎
12:55
|
(121) есть, например, https://ru.wikipedia.org/wiki/D-Bus
|
|||
131
fisher
13.05.15
✎
13:01
|
(130) О! Наконец-то ответ по существу.
Спасибо, буду знать. |
|||
132
Torquader
13.05.15
✎
13:55
|
(130) Это, скорее, реализация механизма, похожего на очередь сообщений в Windows.
|
|||
133
fisher
13.05.15
✎
15:17
|
(132) Не. MSMQ скорее всё же про межсистемное взаимодействие, чем про межпроцессное. И никаких плюшек близких к задачам COM базово не имеет.
А D-Bus в самом деле неплохо покрывает задачи COM, судя по описанию. Хотя в отличие от COM (в простейшем случае) подразумевает асинхронное взаимодействие, что усложняет. |
|||
134
Torquader
13.05.15
✎
15:27
|
(133) В COM тип взаимодействия выбирается из размещения объектов, если в одном потоке, то будут прямые вызовы, если нет, то будет асинхронное обращение с ожиданием.
Вот как раз ожидание в COM-взаимодействии и напрягает. |
|||
135
Torquader
13.05.15
✎
15:28
|
Кстати, у Microsoft ещё есть замечательные механизмы NamedPipe и MailSlot, которые позволяют процессам обмениваться данными.
|
|||
136
H A D G E H O G s
13.05.15
✎
20:51
|
(135) Эти механизмы (NamedPipe) дают фантастическое быстродействие в режиме "Процесс" - "Процесс".
Странно, что они не используются в кластере 1С. |
|||
137
Serginio1
13.05.15
✎
21:09
|
(97) http://www.delphisources.ru/pages/faq/base/interface_idispatch.html
Если вспомнить Delphi и CreateOleObject Com это IUnknown https://ru.wikipedia.org/wiki/Microsoft_OLE_Automation OLE Automation — технология компании Microsoft, позволяющая обращаться к COM-объектам из интерпретаторов скриптовых языков, таких, как VBScript (на настоящий момент поддержка обращений к OA-объектам есть в Windows-версиях всех популярных скриптовых языков). История[править | править вики-текст] Впервые появилась около 1993 как замена устаревшей возможности DDE_EXECUTE. Среда программирования Visual Basic была практически полностью основана на OLE Automation, с такими типами данных, как String и Variant. |
|||
138
Serginio1
13.05.15
✎
21:10
|
Объектами OLE Automation являются все элементы управления ActiveX (OCX-контролы). Свойства, методы и события этих компонент реализованы с помощью OLE Automation.
Также объектами OLE Automation являются многие популярные приложения, такие, как компоненты Microsoft Office. Это дает возможность запустить и управлять даннным приложением (например, Excel, например, сформировать программно таблицу, заполнить в ней ячейки и сохранить в файл) из скрипта, написанного на скриптовом языке. Также объектами OLE Automation являются все тэги Dynamic HTML (при использовании Trident или же — вроде как, нужно проверить — Apple WebKit или Google Chrome). Также на этой технологии основана WMI (ее слой, отвечающий за общение с клиентскими программами) и ряд административных утилит Windows, например, управление веб-сервером IIS. |
|||
139
Serginio1
13.05.15
✎
21:14
|
||||
140
Torquader
13.05.15
✎
21:14
|
(138) Wmi основана на COM-сервере, обслуживающем запросы WMI.
Не надо путать OLE и COM - они очень похожи, просто OLE основана на COM-серверах, но COM значительно шире. (136) Named-Pipe это некоторый упрощённый интерфейс для обмена поточными данными. TCP-соединение между машинами бывает даже быстрее (так как named-pipe основан на IP-пакетах). А в рамках одной машины быстрее всего оказывается технология SharedMemory, когда память одного процесса передаётся в другой. Насколько я знаю, и в Windows и в Linux этот режим есть. Только вот вопросы в его безопасности. |
|||
141
Torquader
13.05.15
✎
21:15
|
(139) В delphi COM более развит, чем в Visual Basic, так как можно и свои интерфейсы создавать (что в VB нельзя).
|
|||
142
Serginio1
13.05.15
✎
21:16
|
(134) Все зависит от аппартамета
http://www.introligator.org/articles/3/84 |
|||
143
Serginio1
13.05.15
✎
21:18
|
(141) Я к тому, что OLE Automation это и есть IDispatch
|
|||
144
Torquader
13.05.15
✎
21:23
|
(142) Apartment и есть размещение (или окружение) как его называют.
|
|||
145
Serginio1
13.05.15
✎
21:24
|
143+ IConnectionPointContainer,IConnectionPoint
|
|||
146
Torquader
13.05.15
✎
21:25
|
(143) Automation это раньше было DDE, а теперь COM-сервер с интерфейсом IDispatch.
Только там могут и другие интерфейсы использоваться (обычно два IDispatch в обе стороны - от управляющего команды управляемому и от управляемого события управляющему). |
|||
147
Serginio1
13.05.15
✎
21:25
|
Процесс имеет один или несколько MTA апартаментов и ни одного STA. Эта модель называется моделью свободных потоков (free-threaded model). Для DLL-сервера в реестре будет записан ключ Threadingmodel=”Free”, а для EXE-сервера будет создан апартамент MTA. Клиенты могут вызывать любые методы объекта из любого потока в любое время. Объекты могут обрабатывать любое число потоков в любое время. Они должны защищать глобальные данные и данные экземпляров с помощью критических секций или каким-либо другим методом, защищающим некоторую последовательность кода. Клиенты программируются легко, однако объекты более сложны в разработке. Используется в первую очередь в распределенных средах DCOM Both. Модель смешанных потоков (both-threded model): имеются MTA и STA апартаменты. Для DLL-сервера в реестре будет записан ключ Threadingmodel=”Both”, а для EXE-сервера будет создан апартамент MTA. Объекты могут поддерживать клиентов, которые используют модели apartment или free. Максимум производительности и гибкости. Клиенты могут использовать одно-поточную или многопоточную модель для повышения производительности Neutral. Модель нейтральных потоков (neutral-threaded model), близкая к модели Both. Для DLL-сервера в реестре будет записан ключ Threadingmodel=”Neutral”, а для EXE-сервера будет создан апартамент MTA
Модель нейтральных потоков отличается от модели смешанных потоков тем, что, во-первых, для ее поддержки нужна COM+, и, во-вторых, она несколько упрощает синхронизацию потоков. Суть синхронизации заключается в том, что если какой-либо клиент вызвал метод объекта, то другой клиент не сможет вызвать этот же метод до тех пор, пока метод не завершится. Если все методы работают только со «своими» данными, то в этом случае отпадает необходимость и в синхронизации доступа к полям объекта. |
|||
148
Torquader
13.05.15
✎
21:26
|
Есть ещё IDataObject.
P.S. ты хочешь показать, что хорошо знаешь структуру взаимодействия объектов, но, по-мойму, в этом уже никто не сомневается. |
|||
149
Serginio1
13.05.15
✎
21:27
|
(146) Я это прекрасно понимаю. Просто я к васшему Хэдджехогсом по поводу ОЛЕ,СОМ, АктивИкс
|
|||
150
Torquader
13.05.15
✎
21:28
|
(147) И осталось добавить, что OLE подсистема работает в Single Thread Apartment.
|
|||
151
Torquader
13.05.15
✎
21:28
|
(149) ActiveX изначально вообще были 16-битные, тогда как COM-объекты сразу пошли в 32-бита.
|
|||
152
Serginio1
13.05.15
✎
21:32
|
(150) Нет. IDispatch ничем не отличается от COM. Другое дело если это касается контролов
(151) https://ru.wikipedia.org/wiki/ActiveX Впервые эта технология была внедрена в 1996 году компанией Microsoft как развитие технологий Component Object Model (COM) и Object Linking and Embedding (OLE) и теперь она широко используется в операционных системах семейства Microsoft Windows[источник не указан 1028 дней], хотя сама технология и не привязана к операционной системе. Множество приложений для Microsoft Windows, включая приложения самой компании Microsoft, такие, как Internet Explorer, Microsoft Office, Microsoft Visual Studio, Windows Media Player, используют управляющие элементы ActiveX, чтобы реализовать набор функциональных возможностей и в дополнение инкапсулировать их собственный функционал в управляющие элементы ActiveX, чтобы предоставить возможность встраивать их в другие приложения. |
|||
153
Torquader
13.05.15
✎
21:40
|
ActiveX Control можно и в Web-страницу вставлять, только вот другие браузеры это не понимают.
|
|||
154
Ma3eIIa
13.05.15
✎
22:50
|
мне тема нравиться. ушли хер знает в какие дебри
|
|||
155
Ma3eIIa
13.05.15
✎
22:52
|
(152) так I это то что должно быть реализовано у класса. даже пустая реализация. это же не прямое наследование от класса. а только обязательства у интрефейса. хотя может быть и реализация методов. тогда
это абстрактный класс. но не интерфейс |
|||
156
Torquader
13.05.15
✎
22:54
|
(155) Интерфейс, это не реализация класса - это таблица функций. Про то, что он является классом с виртуальными функциями уже подумали потом.
|
|||
157
Ma3eIIa
13.05.15
✎
22:57
|
(156) это что может должно быть в наследование . верно же ?
|
|||
158
Ma3eIIa
13.05.15
✎
23:00
|
(157) как я пишу веб приложение.
есть дао класс. он абстрактный он имеет сохранить создать и пару методов. есть интерфейс нужного объекта. в нем описаю методы которые нужно. а вот в сервисах описываю их :) так учат.... |
|||
159
Ma3eIIa
13.05.15
✎
23:01
|
(157) может ты еще знаешь wicket+java?
|
|||
160
Torquader
13.05.15
✎
23:01
|
Например, в Си пишется так:
typedef struct tagInterfaceUnknown { struct tagInterfaceUnknownVtbl*lpVtbl; }IUnknown; То есть интерфейс, это структура, содержащая ссылку на таблицу виртуальных функций. Кстати, к вопросу о новом WinAPI - в случае интерфейсов получается, что из DLL нужно узнавать только один указатель на таблицу функций, а не адрес каждой функции - некоторое облегчение при динамическом связывании. |
|||
161
Torquader
13.05.15
✎
23:02
|
(159) C java я как-то не подружился, так как не перевариваю языки, где нельзя принудительно управлять памятью.
|
|||
162
Serginio1
14.05.15
✎
10:35
|
(160) Мало того например в Delphi по отрицательному смещению хранятся ссылки на виртуальные методы ксласса (static) и конструктора
http://rsdn.ru/article/Delphi/delphiabs.xml {Virtual method table entries } vmtSelfPtr = -76; vmtIntfTable = -72; vmtAutoTable = -68; vmtInitTable = -64; vmtTypeInfo = -60; vmtFieldTable = -56; vmtMethodTable = -52; vmtDynamicTable = -48; vmtClassName = -44; vmtInstanceSize = -40; vmtParent = -36; vmtSafeCallException = -32; vmtAfterConstruction = -28; vmtBeforeDestruction = -24; vmtDispatch = -20; vmtDefaultHandler = -16; vmtNewInstance = -12; vmtFreeInstance = -8; vmtDestroy = -4; vmtQueryInterface = 0; vmtAddRef = 4; vmtRelease = 8; vmtCreateObject = 12; Как интересно! Часть из них меньше нуля. Судя по именам констант, вплоть до vmtAfterConstruction (смещение -28) расположены указатели на различные интересные данные. Затем идут указатели на виртуальные методы, декларированные в самом TObject: AfterConstruction, BeforeDestruction, Dispatch, DefaultHandler, NewInstance, FreeInstance, Destroy. Затем идут методы с неотрицательными смещениями. Таким образом, указатель, расположенный в начале объекта, ссылается куда-то «в середину» VMT. И эта середина – ровно то место, с которого будут располагаться виртуальные методы, объявленные в классах-потомках. Из названий констант vmtQueryInterface, vmtAddRef и vmtRelease ясно, зачем так сделано – иначе в потомках TObject было бы невозможно реализовать интерфейс IUnknown. Итак, 4 байта, полученных при вызове TObject.ClassType, указывают в начало таблицы виртуальных методов, декларированных в потомках TObject. Этот вывод можно считать «безопасным» до тех пор, пока Delphi поддерживает совместимость с COM. |
|||
163
Torquader
14.05.15
✎
13:21
|
(162) Это называется Хак - чтобы не портить совместимость со стандартными классами "умные программисты" придумали, чтобы их методы лежали в таблице ниже основных, и передавать указатель на основной.
Также, например, работают SystemString (BSTR), когда передаётся указатель на строку, а перед ней ещё кто-то живёт. Да и с оконными классами тоже есть отрицательные смещения. Ничего в этом страшного нет, пока не будет получен объект, который не имеет отрицательной части - тогда будет или SegmentFault или даже разрушение кучи, если будет выполняться освобождение объекта. Просто, виртуальные таблицы функций обычно константные и живут в коде библиотек, так что нет никаких позывов к их освобождению, а для всех объектов одного и того же класса используется одна и та же таблица виртуальных функций. В java, методы вызываются по имени, поэтому таблицу можно менять как угодно даже в процессе исполнения (кстати, в javascript тоже). |
|||
164
Serginio1
14.05.15
✎
15:20
|
(163) В Net для каждого класса генерится одна VMT где для каждого интерфейса своё смещение
В этом дизайне каждому интерфейсу во время его загрузки присваивается уникальный номер интерфейса (читай порядковый номер интерфейса с момента старта программы — прим. AVK). Каждый класс, который реализует один или несколько интерфейсов, имеет вторичную таблицу интерфейсов, или ITable, которая доступна посредством косвенной ссылки из стандартной VTable. Вызов происходит посредством перенаправления, используя номер интерфейса.Он в свою очередь указывает назад, на секцию нормальной VTable в которой расположены методы, реализующие интерфейс. Конечно, ITable невероятно избыточна. Используемый класс может реализовывать только интерфейсы с номерами 1003 и 2043. Мы нуждаемся только в двух слотах для него, так что будет черезвычайно расточительно тратить 2044 слота (2044 потому что класс не может реализовывать интерфейсы, которые еще не загружены, поэтому реализовать интерфейс с номером, большим 2043 он так же не может. Отсюда требуемый размер ITable — прим. AVK). Следовательно ключевой аспект этого дизайна это то, что все ITable редко расположены в единственном общем хипе. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |