我正在尝试访问来自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);
}
有什么想法吗?
答案 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中,无论是作为数组还是类似的?