C# – Invalid Variant Operation Exception Trying to Access OleVariant in Delphi – Works in C#

c++comdelphiole

I'm trying to access an OleVariant in a callback that is coming from an ActiveX library.

Here's what the event handler is defined as in the TLB:

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

Here's the definition of structVTIQSnap in the TLB:

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;

It compiles fine, but everytime I try to access the bstrSymbol, I get an "Invalid Variant Operation":

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

How do I access structQSnap and its properties in Delphi?

In C#, this function works fine for the event handler:

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

Any ideas?

Best Solution

I think that Delphi's ActiveX import wizard doesn't know how to handle the structVTIQSnap type (which seems to be a record) properly and just uses the default OleVariant. Is there a type declaration named structVTIQSnap or similar in the generated ..._TLB.pas file? Try using that instead of OleVariant, e.g.

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

The type will probably be declared as a "packed record".

Related Question