|
Использование SafeArrayCopy и VariantCopyInd | ☑ | ||
---|---|---|---|---|
0
max735
09.08.12
✎
08:13
|
Здравствуйте,
Подскажите пожалуйста по следующей проблеме: 1С отдает параметры COM серверу, причем есть вероятность того, что в качестве параметра будет передана ссылка на существующий объект. Внутри COM сервера я копирую параметры с помощью функции SafeArrayCopy. К сожалению не понял, при вызове этой функции копируются только значения или ссылка на объект переходит со всей структурой как она есть в источнике? Нужно ли разбирать массив на составляющие и к каждому элементу применять функцию VariantCopyInd, чтобы гарантировать, что дальше будет работа только со значениями? В процессе вышеуказанных манипуляций заметил следующее: 1С передает ссылку на объект в качестве параметра, например ПриходныйОрдер.Номер или ПриходныйОрдер.Дата. После вызова функции 1С начинает ругаться на то, что не может прописать объект. Т.е. внешне это выглядит, как будь-то функция пытается изменить эти значения переданных параметров. Но я у себя для тестов в COM сервере отключил любые манипуляции с параметрами (вообще ничего с ними не делаю и никак не использую). Отсюда делаю вывод, что это сама 1С при передаче параметров что-то делает с ними, а затем воспринимает этот процесс как попытку поменять что-то в существующем документе, переданном по ссылке. Похоже на реальную картину или я ошибаюсь? Спасибо. |
|||
1
H A D G E H O G s
09.08.12
✎
08:29
|
Не делайте так
|
|||
2
H A D G E H O G s
09.08.12
✎
08:30
|
"Делай как я!"
ПеремНомер=ПриходныйОрдер.Номер; ComОбъект.СуперФункция(ПеремНомер); |
|||
3
ДенисЧ
09.08.12
✎
08:30
|
Именно так. При передаче в КОМ объекта 1с детектирует попытку изменения.
|
|||
4
H A D G E H O G s
09.08.12
✎
08:31
|
Я даже не в курсе, как в ComОбъект принять параметр по значению. Лениво и не нужно мне это.
|
|||
5
andrewks
09.08.12
✎
08:51
|
(2) +1 лучше с 1С в такие игры, как передачу ссылок на поля объектов во внешний мир, не играть, имхо
|
|||
6
oleg_km
09.08.12
✎
08:55
|
Причем здесь SafeArray? Если передается объект, то это наверное IDispatch? Дергаешь там его методы и вроде как все должно быть нормально
|
|||
7
max735
10.08.12
✎
00:37
|
Cпасибо всем за ответы,
(1)(2) - Проблема в том, что эту внешнюю компоненту используют сторонние программисты 1С. В принципе 1С не запрещает вставить в качестве параметра ссылку на объект, отсюда и вылезла проблема. Насколько я понимаю, повлиять на нее я не могу. (6) - Дело в том, что в механизме внешней компоненты 1С вызывает функцию этой компоненты и передает ей параметры в виде SAFEARRAY. Задача состоит в том, чтобы эти параметры забрать в виде значений, а не ссылок (чтобы затем случайно в коде внешней компоненты не поменять какое-либо значение в самой 1С). Для этого сейчас перебираю этот массив и к каждому элементу применяю функцию VarianCopyInd, результаты преобразований собираю в новый массив и передаю дальше по цепочке. Примерно так. |
|||
8
H A D G E H O G s
10.08.12
✎
00:51
|
Я никуа не понял.
Внешняя компонента или COM сервер? |
|||
9
H A D G E H O G s
10.08.12
✎
00:52
|
Если внешка - берите Ромикса шаблон и не сношайте мозг, там можно и ссылку передавать и объекты 1С в компоненте создавать и даже! их потом корректно освобождать..
|
|||
10
max735
10.08.12
✎
01:13
|
(9) Суть проблемы в том, что кода 1С передает параметры, она производит действия, которые сама же воспринимает, как попытку изменить объект. Для пользователей 1С это выглядит как-будто внешняя компонента (тоже ведь COM сервер) пытается изменить эти параметры, хотя внешняя компонента ничего еще с ними не делает. По сути это баг 1С, как я это понимаю на текущий момент.
|
|||
11
H A D G E H O G s
10.08.12
✎
01:32
|
Вот так это работает в Дельфи, где
g_Params - параметр PSafeArray, который передается из 1С в компоненту по ссылке function T_vk_object.GetParamAsObject(lIndex:Integer):OleVariant; var varGet:OleVariant; begin SafeArrayGetElement(g_Params,lIndex,varGet); try result:=varGet; except raise Exception.Create('Параметр номер '+inttostr(lIndex+1)+' не может быть преобразован в объект.'); end; end; |
|||
12
orefkov
10.08.12
✎
01:44
|
(10)
Немного не так. В 1С значения хранятся в своем собственном виде (класс core::Value). Когда вызывается метод COM-объекта, для каждого переданного параметра создается копия в виде VARIANT, которая уже и передается в COM-объект. А дальше 1С почему-то считает, что все параметры в COM объект передаются по ссылке. И потому после вызова метода COM-объекта 1С пытается "переложить" значения параметров созданных копий VARIANT обратно в свои Value. Что может приводить либо к модифицированности значений, либо к ошибке, если значение "read only". Поэтому приходится делать через лишнюю переменную. |
|||
13
max735
10.08.12
✎
08:07
|
(12) Спасибо, примерно что-то подобное я и предполагал.
|
|||
14
Serginio1
10.08.12
✎
10:54
|
Посмотри http://1c.proclub.ru/modules/mydownloads/personal.php?cid=115&lid=2019
там есть ВК которая загружает Объект Автоматизации поддерживающий ITypeInfo и выполняет все его свойства и методы через IlanguageExtender И соответственно работа с var параметрами |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |