Имя: Пароль:
1C
1С v8
Использование 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 параметрами