Имя: Пароль:
1C
1C 7.7
v7: 1С 7.7, COM-объекты и out-параметры
0 бомболюк
 
25.09.15
12:43
Добрый день.

Написал на дельфях COM объект, который планирую использовать в 1С 7.7. Проблема в том, что не получается изменив значение параметра метода в теле COM объекта вернуть его в 1С.

Вот описание метода, проблема с параметром OutData:
function DoSomeMethod(const InData: WideString; var OutData: WideString): Integer; safecall;

Подскажите, куда копнуть, все уже перепробовал, но кроме как в результате метода вернуть ничего не получается.
1 Serginio1
 
25.09.15
12:47
Вообще то все параметры в 1с передаются по ссылке.
Если что, можешь через ВК
http://catalog.mista.ru/public/345658/

Исходник ВК, которая загружает Объект Автоматизации, поддерживающий ITypeInfo и выполняет все его свойства и методы через IlanguageExtender
Поддержка Var и Out параметров
2 бомболюк
 
25.09.15
13:01
(1) Что то переделывать все из-за этого совсем не хочется.
3 H A D G E H O G s
 
25.09.15
13:11
(0) Специально для вас создали конструктор интерфейсов и их свойств и методов в Delphi.
4 H A D G E H O G s
 
25.09.15
13:19
Пробуй так:
function DoSomeMethod(const InData: WideString; var OutData: OleVariant): Integer; safecall;
5 Serginio1
 
25.09.15
13:52
(2) А там переделывать ничего не надо.

Загрузить объект в ВК можно двумя способами
    ЗагрузитьВнешнююКомпоненту("AddInFromITypeInfo.dll");
1. Способ
       TypeInfo = СоздатьОбъект("AddIn.AddInFromITypeInfo");
      TypeInfo.LoadOleObject("AddinTypeInfo.AddinTypeInfo");
2.Способ
       д=CreateObject("AddinTypeInfo.AddinTypeInfo");
       Загрузить объект в ВК можно двумя способами
    ЗагрузитьВнешнююКомпоненту("AddInFromITypeInfo.dll");
1. Способ
       TypeInfo = СоздатьОбъект("AddIn.AddInFromITypeInfo");
      TypeInfo.LoadOleObject("AddinTypeInfo.AddinTypeInfo");
2.Способ
       д=CreateObject("AddinTypeInfo.AddinTypeInfo");
       TypeInfo.LoadOleObject(д);
Где     AddInFromITypeInfo.dll это данная ВК;  
AddinTypeInfo.AddinTypeInfo пример Automation Object находящийся в
\VKITypeInfo\AddinTypeInfo
.LoadOleObject(д);
Где     AddInFromITypeInfo.dll это данная ВК;  
AddinTypeInfo.AddinTypeInfo пример Automation Object находящийся в
\VKITypeInfo\AddinTypeInfo


То есть подгрузив в ВК ты вызываешь все методы и свойства твоего оле объекта.
Это просто прокси.

Например

рез=TypeInfo.DoSomeMethod(InData,OutData);

OutData сможешь изменить в своем оле объекте
6 Serginio1
 
25.09.15
13:53
Внутри проверяется параметр по ссылке или по значению


  if FuncDesc.lprgelemdescParam[j].tdesc.vt =VT_PTR   Then
//Данный параметр передается по ссылке
    MethodArray[i].Params[j]:=FuncDesc.lprgelemdescParam[j].tdesc.ptdesc.vt
            Else
// а этот по значению.
    MethodArray[i].Params[j]:=FuncDesc.lprgelemdescParam[j].tdesc.vt;
                    end;
7 Serginio1
 
25.09.15
13:56
Внутри ВК вызов метода твоего объекта

function TAddInObject.CallAsFunc(lMethodNum: Integer; var pvarRetValue: OleVariant; var paParams: PSafeArray{(OleVariant)}): HResult; stdcall;
Var VarResult:OleVariant;
Inf:ExcepInfo;
begin

             if FillParams(MethodArray[lMethodNum],Args,paParams,DispParams)<>S_OK Then
                      begin
                       result:=E_FAIL;
                       RaiseParamError;
                       exit;
                      end;
      FillChar(inf,SizeOf(ExcepInfo),0);
      result:=obj.Invoke(MethodArray[lMethodNum].DispId, GUID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD OR DISPATCH_PROPERTYGET, DispParams, @VarResult, Inf, nil);
      If Result<>S_OK Then
      Begin
               ErrorLog.AddError(nil,@inf);
               result:=E_FAIL
      end
               Else
             Begin
               If TVarData(VarResult).VType = varByRef or varVariant Then
             pvarRetValue:= OleVariant(TvarData(TVarData(VarResult).VPointer^))
             Else
             pvarRetValue:=VarResult
             end;


end;
8 Serginio1
 
25.09.15
14:06
Вот методо заполнения параметров
Function FillParams(Var MethodRecord:TMethodRecord;Var Args:TArgs; var paParams: PSafeArray{(OleVariant)}; var DispParams: TDispParams): HResult;
Var
P:PParamsArray;
i,j:Integer;
begin
             if Length(MethodRecord.Params)=0 Then
                   begin
                   DispParams.rgvarg:=nil;
                   DispParams.rgdispidNamedArgs := nil;
                   DispParams.cArgs := 0;
                   DispParams.cNamedArgs := 0;
                   Result:=S_OK;
                   exit;
                   end;
Try
   Try
   VarResultCheck(SafeArrayGetUBound(paParams,1,j));
   VarResultCheck(SafeArrayGetLBound(paParams,1,i));
    j:=j-i;
    VarResultCheck(SafeArrayAccessData(paParams,Pointer(p)));
    Try
  For i:=0 to j Do
      Begin
   If MethodRecord.Params[i].IsPtr Then
   Begin
//=========================================================
      If MethodRecord.Params[i].ParamType=VT_VARIANT Then
      begin
     Args[j-i].vt:=VT_BYREF  or VT_VARIANT;
     Args[j-i].byRef:=@p^[i];
       end
       else
        begin
        if MethodRecord.Params[i].ParamType<>TvarData(p^[i]).VType Then
      Begin
       If MethodRecord.Params[i].ParamType=VT_DISPATCH Then // Возможно Out параметр
         Begin
          VarClear(p^[i]);
          TvarData(p^[i]).VType:=VT_DISPATCH;
          TvarData(p^[i]).VAny:=nil;
         end
       else
       VarCast(p^[i],p^[i], MethodRecord.Params[i].ParamType);
      end;
       Args[j-i].vt:=VT_BYREF  or TvarData(p^[i]).VType;
       Args[j-i].unkVal:=@TVarData(p^[i]).VAny;
        end;
    end
     else
//==============================================================
     begin
      If MethodRecord.Params[i].ParamType=VT_VARIANT Then
      begin
     Args[j-i].vt:=TVarData(p^[i]).Vtype;
     Args[j-i].dblVal:=TVarData(p^[i]).VDouble;
       end
       else
        begin
        if MethodRecord.Params[i].ParamType<>TvarData(p^[i]).VType Then
      Begin
       If MethodRecord.Params[i].ParamType=VT_DISPATCH Then // Возможно Out параметр
         Begin
          VarClear(p^[i]);
          TvarData(p^[i]).VType:=VT_DISPATCH;
          TvarData(p^[i]).VAny:=nil;
         end
       else
       VarCast(p^[i],p^[i], MethodRecord.Params[i].ParamType);
      end;
       Args[j-i].vt:=TvarData(p^[i]).VType;
       Args[j-i].dblVal:=TVarData(p^[i]).VDouble;
        end;
     end

      end;
              DispParams.rgvarg:=@Args;
              DispParams.rgdispidNamedArgs := nil;
              DispParams.cArgs := j+1;
              DispParams.cNamedArgs := 0;
              Finally
              VarResultCheck(SafeArrayUnaccessData(paParams));

              end;
              finally

              end;
   except
   Result:=S_False;
   exit;
   end;
        Result:=S_OK;
end;