用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;

解决方案 »

  1.   

    OleVariant 不等于 Variant
      

  2.   

    它是原型是:function GetBuffer(var Buffer: {??PSafeArray}OleVariant; TimeOut: Smallint): Integer; dispid 1610809374;引用到delphi中,你要定義一個OleVariant變量再調用
    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的,這樣傳送的位元組資料就會出問題。
      

  3.   

    OleVariant就如 Variant的指針:example:申明 a: OleVariant
    然後申請空間:     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 控制項所寫.
      

  4.   

    to kye_jufei:谢谢你的回复,我在网上找到过类似的文章,按照文章写的方法都试了,还是不行。我现在怀疑是不是控件本身有问题。