用Delphi 调用一个COM组件,引入类型库后,调用其中一个GetBuffer方法,该方法存在一个OleVariant参数,运行时总提示类型不匹配。
代码:
var
Cim:Variant;
V:Variant;
begin
Cim := CreateOleObject('CimioX.Cimio');
V:= VarArrayCreate([0,100],varByte);
Cim.GetBuffer(V,100);//此处编译通过,运行提示“类型不匹配”
end;导入的类型库的定义如下:
// *********************************************************************//
// DispIntf: _CimioDisp
// Flags: (4560) Hidden Dual NonExtensible OleAutomation Dispatchable
// GUID: {97E11287-9BB3-11D3-9116-00C04FA15BDB}
// *********************************************************************//
_CimioDisp = dispinterface
['{97E11287-9BB3-11D3-9116-00C04FA15BDB}']
property EnableErrEvents: WordBool dispid 1745027095;
property PassThruMode: WordBool dispid 1745027094;
property ErrDescription: WideString readonly dispid 1745027092;
property CimType: ePassThru readonly dispid 1745027091;
procedure SendAWrd(WordOut: Smallint; usDelay: Integer); dispid 1610809388;
function SendWrd(WordOut: Smallint; var WordIn: Smallint; Attempts: Byte): WordBool; dispid 1610809369;
function ClearFIFO: WordBool; dispid 1610809370;
function StartReceiveBuffer(WordOut: Smallint; GenEvent: WordBool; TimeOut: Smallint): WordBool; dispid 1610809371;
function GetBuffer(var Buffer: {??PSafeArray}OleVariant; TimeOut: Smallint): Integer; dispid 1610809374;
function SendBuffer(var Buffer: {??PSafeArray}OleVariant; usDelay: Integer): WordBool; dispid 1610809375;
代码:
var
Cim:Variant;
V:Variant;
begin
Cim := CreateOleObject('CimioX.Cimio');
V:= VarArrayCreate([0,100],varByte);
Cim.GetBuffer(V,100);//此处编译通过,运行提示“类型不匹配”
end;导入的类型库的定义如下:
// *********************************************************************//
// DispIntf: _CimioDisp
// Flags: (4560) Hidden Dual NonExtensible OleAutomation Dispatchable
// GUID: {97E11287-9BB3-11D3-9116-00C04FA15BDB}
// *********************************************************************//
_CimioDisp = dispinterface
['{97E11287-9BB3-11D3-9116-00C04FA15BDB}']
property EnableErrEvents: WordBool dispid 1745027095;
property PassThruMode: WordBool dispid 1745027094;
property ErrDescription: WideString readonly dispid 1745027092;
property CimType: ePassThru readonly dispid 1745027091;
procedure SendAWrd(WordOut: Smallint; usDelay: Integer); dispid 1610809388;
function SendWrd(WordOut: Smallint; var WordIn: Smallint; Attempts: Byte): WordBool; dispid 1610809369;
function ClearFIFO: WordBool; dispid 1610809370;
function StartReceiveBuffer(WordOut: Smallint; GenEvent: WordBool; TimeOut: Smallint): WordBool; dispid 1610809371;
function GetBuffer(var Buffer: {??PSafeArray}OleVariant; TimeOut: Smallint): Integer; dispid 1610809374;
function SendBuffer(var Buffer: {??PSafeArray}OleVariant; usDelay: Integer): WordBool; dispid 1610809375;
example:
OLEVariant資料類型,看到Variant就知道這個是個變體,可變為其他的類型,前提是要知道怎麼給它賦值,因為不能直接把array of byte賦給它。這只說明這一種用法,賦值陣列。首先先建立一個變數;
var
test:OLEVariant;
i:integer;然後要分配空間,使用VarArrayCreat(),這個方法在variants單元中,所以確保前面已經包含進這個單元。
varArrayCreat([0,255],varbyte),[0,255]表明分配256個空間,類型為byte。
這一段代碼這樣寫:
test:=VarArrayCreat([0,255],varbyte);
for i:=0 to 255 do
begin
test[i]:=data[i];//data[]為你的要賦給test的陣列
end;之後就可以直接使用test了。例如:mscomm控制項中的輸出
mscomm1.output:=test;會把這個陣列發送出去。採用test而不直接用char(),是因為char()轉換為字元值,而有些byte值沒對應的字元這時,char()會返回0的,這樣傳送的位元組資料就會出問題。
然後申請空間: a:=VarArrayCreate([0, m-1], varByte);
申請 m 個位元組的空間。
然後用 dat: array[0..m] of bye 對a進行賦值,如下:
for i:=0 to m-1 do
begin
a[i]:=dat[i];
end;
這樣就可以了。 a 就是一個陣列。長度 m ,就如Delphi 中的動態陣列一樣。 在程度中我是這樣寫的。procedure TForm1.can0_sendClick(Sender: TObject);
var
a: olevariant;
i:integer;
len:integer;
begin
len:= strtoint(len_0.Text);
if( len>0 ) then
begin
ID0 := strtoint(id_0.Text) ;
RTR0 := strtoint(rtr_0.Text) ; a:=VarArrayCreate([0, len-1], varByte);
for i:=0 to len-1 do
begin
a[i]:=byte(send_edit_0.Text[i+1]);
end;
if( pcican.SEND(0,ID0,RTR0,len,a)) then
begin
form1.StatusBar1.Panels[3].Text:='can0資料發送成功';
end;
olevariant
end;
end上面是發送的程式,下面是接到的,其實接收要簡單,因為 OleVariant 在接收時會自己動申請空間。
buff : OleVariant
然後經過接收的函數申請空間。如下:
pcican.RECEIVE(1,buff ) // SC2102c.oxc 控制項的介面函數。
於是 buff 是指向一個 byte 陣列的指標。引用它的元素其實很簡單: buff [ i ] 就可以了。
我是這樣寫的.procedure TForm1.pcicanCanEvent(ASender: TObject; IntFlag: Smallint);
var
buff: olevariant;
s: array[0..7] of byte;
i:integer;
begin
if((IntFlag and 16)=16) then
begin
if( pcican.RECEIVE(1,buff )) then
begin
for i:=0 to 7 do
begin
s[i]:=buff[i];
end;
can1_rec_memo.Lines.Add(BytesToStr(s));
label19.Caption:=inttostr(pcican.ID);
end;
end
else
if((IntFlag and 1)=1) then
begin
if( pcican.RECEIVE(0,buff )) then
begin
for i:=0 to 7 do
begin
s[i]:=buff[i];
end;
can0_rec_memo.Lines.Add( BytesToStr(s) );
end;
end;
end;上面的程式是針對, 三純的PCI 介面的CAN匯流排界面卡的 ocx 控制項所寫.