Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.09.01;
Скачать: CL | DM;

Вниз

Array[0..7] Of Byte в Activex компонент, Как передать?   Найти похожие ветки 

 
NoXXX   (2007-07-18 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 ©   (2007-07-18 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);


 
Сергей М. ©   (2007-07-18 14:08) [2]


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


И примеров его использования в комплекте поставки нет ?


 
NoXXX   (2007-07-18 14:15) [3]

SlymRO

Попробовал, вылетает такое же исключение :( Читаю, пишут что массивы должны передаваться как SafeArray, но не пойму, как это сделать можно :/


 
NoXXX   (2007-07-18 14:15) [4]

Сергей М

Пример есть, но он на C#, и там всё работает без проблем. А нужно на Delphi написать.


 
Сергей М. ©   (2007-07-18 14:19) [5]


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


ПРиводи его сюда ..


 
NoXXX   (2007-07-18 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[] - это как раз и есть массив байт


 
Сергей М. ©   (2007-07-18 14:27) [7]


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


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

ПРиведи ..


 
NoXXX   (2007-07-18 14:29) [8]


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


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

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

В принципе, то же самое.


 
umbra ©   (2007-07-18 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 ©   (2007-07-18 14:35) [10]


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

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


 
NoXXX   (2007-07-18 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   (2007-07-18 14:39) [12]


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


Пробовал декларацию править, PrivateAlias на pointer - ругается, Illegal type in OLE automation section "pointer". Не хочет принимать указатель он :(


 
NoXXX   (2007-07-18 14:47) [13]

Попробовал в [1] вместо Int64 использовать String. Значение принял, не ругнулся, но выскочила ошибка, говорящая, что код неверен. Т.е. метод значение получил, но не "ACOSTEST". Куда еще можно копать?


 
umbra ©   (2007-07-18 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 ©   (2007-07-18 15:00) [15]

соответственно

type
PrivateAlias1 = Integer;


 
NoXXX   (2007-07-18 15:24) [16]

Спасибо! Получилось! :)


 
SlymRO ©   (2007-07-19 05:17) [17]

тогда и это должно сработать: Integer(pointer(PChar("ACOSTEST")))



Страницы: 1 вся ветка

Текущий архив: 2013.09.01;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.005 c
15-1364407192
ThreadMaster
2013-03-27 21:59
2013.09.01
Как нужно делать многопоточные приложения


15-1364325103
TStas
2013-03-26 23:11
2013.09.01
А написал ли сам MicroSoft что-то на C#?


15-1364278811
N.Cage
2013-03-26 10:20
2013.09.01
Amd vs Intel


15-1363938287
Pit
2013-03-22 11:44
2013.09.01
Посоветуйте базу данных! :-)


1-1312192872
Zoro
2011-08-01 14:01
2013.09.01
Работа с gzip.dll