Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Несовпадение типов при передаче параметров в OLE компоненту  [new]
ssergio
Member

Откуда:
Сообщений: 19
Доброго дня!
Пытаюсь управлять карточным пинпадом c Arcus2 из Дельфи. Он управляется библиотекой ArcCom.dll
По документации сделал JS код, работает отлично. Там всего 7 строчек:
                        var termReq =  new ActiveXObject('ArcCom.SAPacketObj.1');
			var termResp =  new ActiveXObject('ArcCom.SAPacketObj.1');
			var ap2 = new ActiveXObject('ArcCom.PCPOSTConnectorObj.1');
			termReq.OperationCode = 1;
			termReq.Amount = 100;
			termReq.CurrencyCode = 643;
			result = ap2.Exchange(termReq, termResp, 15);			


Но, надо в Дельфи. А в ней возникает ошибка "несовпадение типов". Я догадываюсь, что из-за передачи параметра в OLE компоненту по значению, а надо по ссылке. Вообще мануал говорит так: создайте объект Request, объект Response и вызовите метод Exchange, который в Response вернёт результат работы. Выходит, Response надо передать по ссылке.


var res : integer;
    termReq : OleVariant;
    termResp : OleVariant;
    AP2 : OleVariant;
begin
    termReq :=  CreateOleObject('ArcCom.SAPacketObj.1');
    termResp := CreateOleObject('ArcCom.SAPacketObj.1');
    AP2 :=      CreateOleObject('ArcCom.PCPOSTConnectorObj.1');
    termReq.OperationCode := 1;
    termReq.Amount := '100';
    termReq.CurrencyCode := '643';
    res := AP2.Exchange(termReq, termResp, 15);
    ShowMessage(IntToStr(res));
end;



Для похожего оборудования поддержка на код Err=CPT.OleFunction("LinkTest","8300");
отвечала в таком ключе, но без конкретики: "Согласно документации на OLE-компоненту метод LinkTest в качестве аргумента принимает ссылку на строку, в которую OLE-компонента записывает модель терминала. В приведенном фрагменте кода в метод LinkTest передается константная строка".

В самой dll объекты объявлены как интерфейсы.
 ISAPacketObj = interface(IDispatch)
 SAPacketObj = ISAPacketObj;
 //Метод Exchange такой:  
 function Exchange(var Request: ISAPacketObj; var Response: ISAPacketObj; Timeout: Integer): Integer; safecall;


Но, я то передаю объект. Вроде как он и так передаётся по ссылке?
Как правильно написать?
19 фев 21, 04:25    [22283225]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
Соколинский Борис
Member

Откуда: Москва
Сообщений: 14191
ssergio
Я догадываюсь, что из-за передачи параметра в OLE компоненту по значению, а надо по ссылке.
Ты не угадал.
Подозреваю что ошибка выскакивает еще тут:
termReq.Amount := '100';
о чем тебе недвусмысленно сообщают - хотят число а ты даешь строку.
19 фев 21, 07:05    [22283235]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
ssergio
Member

Откуда:
Сообщений: 19
не-а. Если б было так просто, увы.
Полез в dll проверить параметры:

ISAPacketObj = interface(IDispatch)
    property CurrencyCode: WideString
    property Amount: WideString
    property OperationCode: Integer 


На termReq.Amount := 100; логично сообщает: Incompatible types WideString and Integer.
В OLE используются строки WideString, а не string.

Теперь ищу как правильно конвертнуть string '100' в widestring.
termReq.Amount := PWideChar(WideString('100')); выдает type not allowed in ole automation call

Сообщение было отредактировано: 19 фев 21, 09:21
19 фев 21, 09:22    [22283256]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
Zelius
Member

Откуда: Россия, Москва
Сообщений: 1522
ssergio,

какая версия Delphi? На какой строчке точно происходит ошибка и ее полный текст?
19 фев 21, 09:34    [22283260]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
Соколинский Борис
Member

Откуда: Москва
Сообщений: 14191
ssergio
Полез в dll проверить параметры:
А откуда взялась DLL для out-proc COM объекта?
19 фев 21, 09:40    [22283264]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
ssergio
Member

Откуда:
Сообщений: 19
Zelius, версия Дельфи пробовал на обоих. И на 7 и на Studio 10 Seatle.
Ошибка Exception Class EOLESysError message 'Несовпадение типов'
на строке метода Exchange:
res := AP2.Exchange(termReq, termResp, 15);
19 фев 21, 09:53    [22283269]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
Соколинский Борис
Member

Откуда: Москва
Сообщений: 14191
ssergio,
Короче, импортируй библиотеку типов "ArcCom..." и выложи сюда декларацию "TPCPOSTConnectorObj..."
19 фев 21, 10:05    [22283275]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
goldmi45
Member

Откуда:
Сообщений: 1263
ssergio

Для похожего оборудования поддержка на код Err=CPT.OleFunction("LinkTest","8300");
отвечала в таком ключе, но без конкретики: "Согласно документации на OLE-компоненту метод LinkTest в качестве аргумента принимает ссылку на строку, в которую OLE-компонента записывает модель терминала. В приведенном фрагменте кода в метод LinkTest передается константная строка".

В этом случае ошибка из-за того, что в метод вы передавали строку "8300", которая является константой, т.е. не может быть выходным параметром.

По существу вопроса. Пытались приводить OleVariant к нужному интерфейсу?

Сообщение было отредактировано: 19 фев 21, 10:02
19 фев 21, 10:08    [22283280]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
ssergio
Member

Откуда:
Сообщений: 19
Соколинский Борис
ssergio,
Короче, импортируй библиотеку типов "ArcCom..." и выложи сюда декларацию "TPCPOSTConnectorObj..."


TPCPOSTConnectorObj = class(TOleControl)
  private
    FIntf: IPCPOSTConnectorObj;
    function  GetControlInterface: IPCPOSTConnectorObj;
  protected
    procedure CreateControl;
    procedure InitControlData; override;
  public
    function InitResources: Integer;
    procedure FreeResources;
    function SetChanelParam(const IPAddress: WideString; IPPort: Integer; const to_: WideString): Integer;
    function SetProtocolParam(TimeoutAck: Integer; TimeoutPacket: Integer; CountNAK: Integer; 
                              PacketSize: Integer): Integer;
    function Exchange(var Request: ISAPacketObj; var Response: ISAPacketObj; Timeout: Integer): Integer;
    function SetControlServerParam(const IPAddress: WideString; IPPort: Integer; Timeout: Integer): Integer;
    function ControlServerStart: Integer;
    function ControlServerStop: Integer;
    function ReadCardHash(out Last4Digits: WideString; out Hash: WideString; out BIN: WideString): Integer;
    function GetReaderSerialNumber(out serial: WideString): Integer;
    function GetReaderDialogsConfig(out config: WideString): Integer;
    function ReadCardHash2(out Last4Digits: WideString; out Hash: WideString): Integer;
    function ReadCard2(out Digits: WideString): Integer;
    function SignatureCapture(const text: WideString; out Signature: WideString): WordBool;
    function SignatureSetPath(const path: WideString): WordBool;
    function ReadBarcode(out buffer: WideString): Integer;
    property  ControlInterface: IPCPOSTConnectorObj read GetControlInterface;
    property  DefaultInterface: IPCPOSTConnectorObj read GetControlInterface;
  published
    property Anchors;
    property ErrorDescription: WideString index 6 read GetWideStringProp write SetWideStringProp stored False;
    property ErrorCode: Smallint index 7 read GetSmallintProp write SetSmallintProp stored False;
  end;



Меня беспокоит, что в объявлении метода Exchange параметр ISAPacketObj, а я создаю СОМ объекты SAPacketObj.
19 фев 21, 10:27    [22283290]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
Соколинский Борис
Member

Откуда: Москва
Сообщений: 14191
ssergio
Меня беспокоит, что в объявлении метода Exchange параметр ISAPacketObj, а я создаю СОМ объекты SAPacketObj.
Это нормально, OleVariant может IDispatch cодержать, а интерфейс ISAPacketObj от него наследуется.
Смущает var в декларации метода.
Попробуй так:
var res : integer;
    termReq, termResp : OleVariant;
    termReqI, termRespI : IDispatch;
    AP2 : OleVariant;
begin
    termReq :=  CreateOleObject('ArcCom.SAPacketObj.1');
    termResp := CreateOleObject('ArcCom.SAPacketObj.1');
    AP2 :=      CreateOleObject('ArcCom.PCPOSTConnectorObj.1');
    termReq.OperationCode := 1;
    termReq.Amount := '100';
    termReq.CurrencyCode := '643';
    timeReqI := TimeReq;
    timeRespI:= TimeResp;

    res := AP2.Exchange(termReqI, termRespI, 15);
    ShowMessage(IntToStr(res));
end;
19 фев 21, 10:40    [22283299]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
ssergio
Member

Откуда:
Сообщений: 19
[quot goldmi45#22283280]
ssergio

По существу вопроса. Пытались приводить OleVariant к нужному интерфейсу?


В руководстве администратора Arcus написано
Для работы с Connector рекомендуется следующая последовательность действий:
1. Создать Request экземпляр объекта ISAPacketObj для пересылки данных Server для
проведения транзакции.
2. Создать Response экземпляр объекта ISAPacketObj для получения результатов транзакции
от Server.
3. Создать экземпляр объекта IConnector Obj для организации каналов обмена данными с
Server.
4. Подготовить данные для проведения транзакции, заполнив соответствующие поля в
Request.
5. Послать запрос на проведение транзакции вызовом метода Exchange.


Даёт создать только termResp := CreateOleObject('ArcCom.SAPacketObj');
Ругается на CreateOleObject('ArcCom.ISAPacketObj') : OleSysError недопустимая строка с названием класса.
19 фев 21, 10:42    [22283300]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
Zelius
Member

Откуда: Россия, Москва
Сообщений: 1522
ssergio,

имхо, дело в параметрах, попробуй без строк их передавать, как целое. у тебя используется Dipatch, а там магия. можно попробовать поотлаживать, вдруг ошибка до оле объекта. или использовать интерфейсы напрямую, там прозрачнее
19 фев 21, 10:42    [22283301]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
ssergio
Member

Откуда:
Сообщений: 19
Соколинский Борис

Попробуй так:


Заработало! Вы - гений! Огромное спасибо!
Пару очевидных опечаток исправил.

Надо приводить OleVariant к IDispatch? Никогда в жизни б не догадался.
19 фев 21, 10:47    [22283307]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
Соколинский Борис
Member

Откуда: Москва
Сообщений: 14191
ssergio
Надо приводить OleVariant к IDispatch?
В нормальных случаях - нет.
Но тут особый*, ламеру поручили API делать.
* - а может уже и нет.
19 фев 21, 11:17    [22283325]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 12572
ssergio,

А зачем вам вообще OleVariant? Используйте раннее связывание
var res : integer;
    termReq, termResp : ISAPacketObj;
    AP2 : IPCPOSTConnectorObj;
begin
    termReq :=  CreateOleObject('ArcCom.SAPacketObj.1') as ISAPacketObj;
    termResp := CreateOleObject('ArcCom.SAPacketObj.1') as ISAPacketObj;
    AP2 :=      CreateOleObject('ArcCom.PCPOSTConnectorObj.1') as IPCPOSTConnectorObj;
    termReq.OperationCode := 1;
    termReq.Amount := '100';
    termReq.CurrencyCode := '643';
    timeReqI := TimeReq;
    timeRespI:= TimeResp;

    res := AP2.Exchange(termReqI, termRespI, 15);
    ShowMessage(IntToStr(res));
end;
19 фев 21, 11:28    [22283331]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
Соколинский Борис
Member

Откуда: Москва
Сообщений: 14191
_Vasilisk_
А зачем вам вообще OleVariant? Используйте раннее связывание
Да ну нафиг.
Потом эти друзья выпустят patch/обновление в котором добавят метод в интерфейс и "здравствуйте товарищи" (с)
19 фев 21, 11:36    [22283338]     Ответить | Цитировать Сообщить модератору
 Re: Несовпадение типов при передаче параметров в OLE компоненту  [new]
Кроик Семён
Member

Откуда: СПб --> Dortmund
Сообщений: 6694
ssergio,

давным-давно была у меня ситуация примерно как у вас, когда OLE-обьект совершенно непонятно работал и лишь саппорт разработчика подсказал, что я инициализирую какое-то там OleVariant свойство неверным типом данных. Ибо свойство ожидало тип знаковый INTEGER , а я ему передавал беззнаковый DWORD.

Это выражалось таким образом

Я писал что-то типа
obj.X := 150;



А надо было, что бы компилятор ясно понял, что это INTEGER, так

1) либо
var
   AnyX : integer;
begin
   AnyX := 150;
   obj.X := AnyX;


2) либо так (я на этом варианте остановился)
obj.X := integer(150);


Сообщение было отредактировано: 19 фев 21, 11:50
19 фев 21, 11:47    [22283349]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить