Конференция "Corba" » Array[0..7] Of Byte в Activex компонент, Как передать? [Delphi, Windows]
 
  • NoXXX (18.07.07 13:34) [0]
    Всем доброго здоровья.

    Проблема заключается вот в чем. У меня есть считыватель карт, вместе с которым идет ActiveX-компонент для работы с ним. Импортировал я библиотеку типов, там присутствует следующее:

    type
    PrivateAlias1 = array[0..7] of Byte;

    В описании функций этот тип передается в качестве параметра:

    function WriteSecurityKey_FN(nKey: Smallint; baKey: PrivateAlias1): Integer; dispid 46;

    При компиляции модуля на каждую такую функцию выдаётся ошибка:

    [Error] ESDKLib_TLB.pas [XXX]: Illegal type in OLE automation section: 'PrivateAlias1'

    Порывшись в инете я понял, что массив байт - это COM-несовместивый тип данных, и что нужно пользоваться функцией VarArrayCreate, предварительно описав этот PrivateAlias1 как OleVariant.

    Вот кусок кода:

    procedure TForm1.Button1Click(Sender: TObject);
    var
     card : IACOS1Card;
     fil : ISCardFile;
     myICCODE : OleVariant;
    begin
     MyICCode := VarArrayCreate([0,7], varByte);
     myICCODE[0] := $41;     // A
     myICCODE[1] := $43;     // C
     myICCODE[2] := $4F;     // O
     myICCODE[3] := $53;     // S
     myICCODE[4] := $54;     // T
     myICCODE[5] := $45;    // E
     myICCODE[6] := $53;    // S
     myICCODE[7] := $54;    // T
     card := CoACOS1Card.Create;
     card.LoadReaderList();
     card.Connect(card.GetReaderName(0));
     card.SubmitCode_FN(IC_CODE, myICCODE);
     fil := CoSCardFile.Create;
     card.CreateFile(fil);
     card.Disconnect;
     card.ReleaseContent;
    end;



    При выполнении функции SubmitCode_FN вываливается exception (EAccessViolation) в модуле ESDK.dll, т.е., насколько я понимаю, эта самая библиотека не воспринимает myICCODE как массив.

    Помогите, пожалуйста, я уже не знаю что делать.

    PS: ESDK.dll изначально написана на Си.

    PPS: В исходниках ESDK.dll функция описана как STDMETHODIMP CACOS1Card::SubmitCode_FN(SHORT nKey,BYTE baKey[8],BOOL* bSuccess)
    В Си я "не в зуб ногой", так что не знаю, поможет ли это уточнение или нет :/
  • SlymRO © (18.07.07 13:57) [1]
    попробуй int64
    function WriteSecurityKey_FN(nKey: Smallint; baKey: int64): Integer; dispid 46;


    type
     TInt64Rec=packed record
       case boolean of
         false: (AsArray: array[0..7] of Byte);
         true: (AsInt64:int64);
       end;

    myICCODE : TInt64Rec;
    begin
    myICCODE.AsArray[0] := $41;     // A
    myICCODE.AsArray[1] := $43;     // C
    myICCODE.AsArray[2] := $4F;     // O
    myICCODE.AsArray[3] := $53;     // S
    myICCODE.AsArray[4] := $54;     // T
    myICCODE.AsArray[5] := $45;    // E
    myICCODE.AsArray[6] := $53;    // S
    myICCODE.AsArray[7] := $54;    // T
    card.SubmitCode_FN(IC_CODE, myICCODE.AsInt64);

  • Сергей М. © (18.07.07 14:08) [2]

    > вместе с которым идет ActiveX-компонент для работы с ним


    И примеров его использования в комплекте поставки нет ?
  • NoXXX (18.07.07 14:15) [3]
    SlymRO

    Попробовал, вылетает такое же исключение :( Читаю, пишут что массивы должны передаваться как SafeArray, но не пойму, как это сделать можно :/
  • NoXXX (18.07.07 14:15) [4]
    Сергей М

    Пример есть, но он на C#, и там всё работает без проблем. А нужно на Delphi написать.
  • Сергей М. © (18.07.07 14:19) [5]

    > Пример есть, но он на C#


    ПРиводи его сюда ..
  • NoXXX (18.07.07 14:24) [6]
    Вот на C#:

    card.LoadReaderList()
    string strReader = card.GetReaderName( 0 );
    card.Connect( strReader );
    byte[] baIC_CODE = Str2ByteAr("ACOSTEST");
    card.SubmitCode_FN( (int)SUB_CODE.IC_CODE, baIC_CODE);



    Как я понимаю, byte[] - это как раз и есть массив байт
  • Сергей М. © (18.07.07 14:27) [7]

    > В описании функций этот тип передается в качестве параметра:
    >
    >
    > function WriteSecurityKey


    А где собссно TLB-описание метода SubmitCode_FN ?

    ПРиведи ..
  • NoXXX (18.07.07 14:29) [8]

    > А где собссно TLB-описание метода SubmitCode_FN ?


    Ай, ошибся, извините :)

    function  SubmitCode_FN(nSubmitKey: Smallint; baKey: PrivateAlias1): Integer; dispid 47;

    В принципе, то же самое.
  • umbra © (18.07.07 14:33) [9]

    > SubmitCode_FN(SHORT nKey,BYTE baKey[8],BOOL* bSuccess)

    судя по всему, метод ждет от Вас адреса первого элемента массива. Передавая же SafeArray вы передаете адрес служебной структуры. Передавая ему
    myICCODE.AsInt64

    вы передаете 8-байтовое число, которое интерпретируется как адрес. Поэтому попробуйте в [1] заменить
    card.SubmitCode_FN(IC_CODE, myICCODE.AsInt64);


    на

    card.SubmitCode_FN(IC_CODE, @myICCODE);

  • umbra © (18.07.07 14:35) [10]

    > function  SubmitCode_FN(nSubmitKey: Smallint; baKey: PrivateAlias1):
    >  Integer; dispid 47;

    и декларацию тоже надо поправить, конечно
  • NoXXX (18.07.07 14:37) [11]

    > Поэтому попробуйте в [1] заменить card.SubmitCode_FN(IC_CODE,
    >  myICCODE.AsInt64);на card.SubmitCode_FN(IC_CODE, @myICCODE);
    >


    на
    card.SubmitCode_FN(IC_CODE, @myICCODE)

    ругается на несовместимость типов Int64 и Pointer :(
  • NoXXX (18.07.07 14:39) [12]

    > и декларацию тоже надо поправить, конечно


    Пробовал декларацию править, PrivateAlias на pointer - ругается, Illegal type in OLE automation section 'pointer'. Не хочет принимать указатель он :(
  • NoXXX (18.07.07 14:47) [13]
    Попробовал в [1] вместо Int64 использовать String. Значение принял, не ругнулся, но выскочила ошибка, говорящая, что код неверен. Т.е. метод значение получил, но не 'ACOSTEST'. Куда еще можно копать?
  • umbra © (18.07.07 14:57) [14]
    да, надо все по науке :)

    type
    type
    TPrivateArray = array[0..7] of Byte;
    PPrivateArray = ^TPrivateArray;
    {................................}
    var
      myICCODE : TPrivateArray;
      mypointer: PPrivateArray;
    {....................................}
    begin
    myICCODE[0] := $41;     // A
    myICCODE[1] := $43;     // C
    myICCODE[2] := $4F;     // O
    myICCODE[3] := $53;     // S
    myICCODE[4] := $54;     // T
    myICCODE[5] := $45;    // E
    myICCODE[6] := $53;    // S
    myICCODE[7] := $54;    // T
    mypointer := @myICCODE;
    card.SubmitCode_FN(IC_CODE, Integer(mypointer));

  • umbra © (18.07.07 15:00) [15]
    соответственно

    type
    PrivateAlias1 = Integer;

  • NoXXX (18.07.07 15:24) [16]
    Спасибо! Получилось! :)
  • SlymRO © (19.07.07 05:17) [17]
    тогда и это должно сработать:
    Integer(pointer(PChar('ACOSTEST')))

 
Конференция "Corba" » Array[0..7] Of Byte в Activex компонент, Как передать? [Delphi, Windows]
Есть новые Нет новых   [134431   +9][b:0][p:0.003]