0

我试图在来自 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

4 回答 4

8

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

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

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

于 2009-01-27T17:12:11.957 回答
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)太小了?

于 2009-01-27T16:33:23.483 回答
0

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

可能会起作用:

 var
   symbol: WideString;
   rec: structVTIQSnap;
 begin
    rec := structVTIQSnap(structQSnap);
    symbol := rec.bstrSymbol; 
 end;
于 2009-01-27T15:45:34.300 回答
0

我不确定您为什么将“structVTIQSnap”视为“OleVariant”。对我来说似乎是一个奇怪的翻译。是不是它已经以某种形式(作为数组或类似形式)放入 OleVariant 中?

于 2009-01-27T16:10:06.323 回答