|
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; |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |