尝试在Delphi中访问OleVariant的变量操作异常无效 - 在C#中工作

时间:2009-01-27 15:29:41

标签: c# delphi com ole

我正在尝试访问来自ActiveX库的回调中的OleVariant。

以下是在TLB中定义事件处理程序的内容:

procedure(ASender: TObject; var structQSnap: {??structVTIQSnap}OleVariant) of object;

以下是TLB中structVTIQSnap的定义:

structVTIQSnap = packed record
  bstrSymbol: WideString;
  bstrListingExch: WideString;
  bstrLastExch: WideString;
  fLastPrice: Double;
  nLastSize: Integer;
  bstrBbo: WideString;
  bstrBidExch: WideString;
  fBidPrice: Double;
  nBidSize: Integer;
  bstrAskExch: WideString;
  fAskPrice: Double;
  nAskSize: Integer;
  fHighPrice: Double;
  fLowPrice: Double;
  fOpenPrice: Double;
  fClosePrice: Double;
  nCumVolume: Integer;
  bstrTradeCondition: WideString;
  nQuoteCondition: Integer;
  bstrCompanyName: WideString;
  f52WeekHigh: Double;
  f52WeekLow: Double;
  fEps: Double;
  nSharesOutstanding: Integer;
  nSpCode: Integer;
  fBeta: Double;
  bstrExDivDate: WideString;
  nDivFreq: Integer;
  fDivAmt: Double;
  nAvgVolume: Integer;
  bstrCusip: WideString;
  fVwap: Double;
  bstrUpdateTime: WideString;
  bstrExch: WideString;
  nSharesPerContract: Integer;
end;

它编译得很好,但每次我尝试访问bstrSymbol时,我都会得到一个“无效的变体操作”:

 procedure TForm1.HandleVTIQuoteSnap(ASender: TObject; var structQSnap: OleVariant);
 var
    symbol: WideString;
 begin
    symbol := structQSnap.bstrSymbol; // this line causes the exception
 end;

如何在Delphi中访问structQSnap及其属性?

在C#中,此函数适用于事件处理程序:

    void vtiQ_OnVTIQSnap(ref vtiLib.structVTIQSnap structQSnap)
    {
        MessageBox.Show("Got qsnap for " + structQuoteSnap.bstrSymbol);            
    }

有什么想法吗?

4 个答案:

答案 0 :(得分:8)

我认为Delphi的ActiveX导入向导不知道如何正确处理structVTIQSnap类型(这似乎是一个记录),只使用默认的OleVariant。 在生成的..._ TLB.pas文件中是否有一个名为structVTIQSnap或类似的类型声明?尝试使用它而不是OleVariant,例如

procedure (ASender: TObject; var structQSnap: structVTIQSnap) of object;

该类型可能会被声明为“打包记录”。

答案 1 :(得分:1)

您可以尝试将 structQSnap 类型转换为指向此结构的指针。像

这样的东西
PstructVTIQSnap = ^structVTIQSnap;
structVTIQSnap = packed record
   bstrSymbol: WideString;
   // other stuff...
end;

procedure TForm1.HandleVTIQuoteSnap(ASender: TObject;
  var structQSnap: OleVariant);
var
  ps: PstructVTIQSnap;
  symbol: WideString;
begi
  ps := PstructVTIQSnap(structQSnap.VPointer^);
  symbol := ps.bstrSymbol;
  ...
end;

我不明白的是以下内容:我从C#代码中的 ref 中取出它,结构应该被编组两次,一次从库到回调,第二次回到图书馆。这意味着需要在VType中设置varByRef标志($ 4000),但是您在评论(3484)中给出的值太小了?

答案 2 :(得分:0)

尝试查看TVarData(structQSnap).VType中的返回值?

可能会起作用:

 var
   symbol: WideString;
   rec: structVTIQSnap;
 begin
    rec := structVTIQSnap(structQSnap);
    symbol := rec.bstrSymbol; 
 end;

答案 3 :(得分:0)

我不确定你为什么认为“structVTIQSnap”是“OleVariant”。对我来说似乎是一个奇怪的翻译。难道它是以某种形式被放置到OleVariant中,无论是作为数组还是类似的?