![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Array[0..7] Of Byte в Activex компонент, Как передать? [Delphi, Windows]
NoXXX © (2007-07-18 13:34:00)Всем доброго здоровья.
Проблема заключается вот в чем. У меня есть считыватель карт, вместе с которым идет 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-19 05:17:00) [1]тогда и это должно сработать:
Integer(pointer(PChar('ACOSTEST')))
NoXXX (2007-07-18 15:24:00) [2]Спасибо! Получилось! :)
umbra (2007-07-18 15:00:00) [3]соответственно
type
PrivateAlias1 = Integer;
umbra (2007-07-18 14:57:00) [4]да, надо все по науке :)
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));
NoXXX (2007-07-18 14:47:00) [5]Попробовал в [1] вместо Int64 использовать String. Значение принял, не ругнулся, но выскочила ошибка, говорящая, что код неверен. Т.е. метод значение получил, но не 'ACOSTEST'. Куда еще можно копать?
NoXXX (2007-07-18 14:39:00) [6]
> и декларацию тоже надо поправить, конечно
Пробовал декларацию править, PrivateAlias на pointer - ругается, Illegal type in OLE automation section 'pointer'. Не хочет принимать указатель он :(
NoXXX (2007-07-18 14:37:00) [7]
> Поэтому попробуйте в [1] заменить card.SubmitCode_FN(IC_CODE,
> myICCODE.AsInt64);на card.SubmitCode_FN(IC_CODE, @myICCODE);
>
наcard.SubmitCode_FN(IC_CODE, @myICCODE)ругается на несовместимость типов Int64 и Pointer :(
umbra (2007-07-18 14:35:00) [8]
> function SubmitCode_FN(nSubmitKey: Smallint; baKey: PrivateAlias1):
> Integer; dispid 47;
и декларацию тоже надо поправить, конечно
umbra (2007-07-18 14:33:00) [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);
NoXXX (2007-07-18 14:29:00) [10]
> А где собссно TLB-описание метода SubmitCode_FN ?
Ай, ошибся, извините :)
function SubmitCode_FN(nSubmitKey: Smallint; baKey: PrivateAlias1): Integer; dispid 47;
В принципе, то же самое.
Сергей М. (2007-07-18 14:27:00) [11]
> В описании функций этот тип передается в качестве параметра:
>
>
> function WriteSecurityKey
А где собссно TLB-описание метода SubmitCode_FN ?
ПРиведи ..
NoXXX (2007-07-18 14:24:00) [12]Вот на 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:19:00) [13]
> Пример есть, но он на C#
ПРиводи его сюда ..
NoXXX (2007-07-18 14:15:00) [14]Сергей М
Пример есть, но он на C#, и там всё работает без проблем. А нужно на Delphi написать.
NoXXX (2007-07-18 14:15:00) [15]SlymRO
Попробовал, вылетает такое же исключение :( Читаю, пишут что массивы должны передаваться как SafeArray, но не пойму, как это сделать можно :/
Сергей М. (2007-07-18 14:08:00) [16]
> вместе с которым идет ActiveX-компонент для работы с ним
И примеров его использования в комплекте поставки нет ?
SlymRO (2007-07-18 13:57:00) [17]попробуй 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);