Ungültige Variante Bedienung Exception OleVariant in Delphi zugreifen möchte - Werke in C #
Frage
Ich versuche, eine OleVariant in einem Rückruf zuzugreifen, die von einer ActiveX-Bibliothek kommen.
Hier ist, was die Event-Handler wie im TLB definiert ist:
procedure(ASender: TObject; var structQSnap: {??structVTIQSnap}OleVariant) of object;
Hier ist die Definition von structVTIQSnap im 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;
Es kompiliert gut, aber jedes Mal wenn ich versuche, die bstrSymbol zuzugreifen, erhalte ich eine "Invalid Variant Operation":
procedure TForm1.HandleVTIQuoteSnap(ASender: TObject; var structQSnap: OleVariant);
var
symbol: WideString;
begin
symbol := structQSnap.bstrSymbol; // this line causes the exception
end;
Wie kann ich structQSnap und seine Eigenschaften in Delphi?
In C # diese Funktion arbeitet für die Event-Handler in Ordnung:
void vtiQ_OnVTIQSnap(ref vtiLib.structVTIQSnap structQSnap)
{
MessageBox.Show("Got qsnap for " + structQuoteSnap.bstrSymbol);
}
Irgendwelche Ideen?
Lösung
Ich denke, dass Delphi ActiveX-Import-Assistenten nicht weiß, wie die structVTIQSnap Art zu behandeln (die einen Datensatz zu sein scheint) richtig und nur verwendet die Standard OleVariant. Gibt es eine Art Erklärung namens structVTIQSnap oder ähnlich in dem erzeugten ..._ TLB.pas Datei? Versuchen Sie es mit, dass anstelle von OleVariant, z.
procedure (ASender: TObject; var structQSnap: structVTIQSnap) of object;
Der Typ wird wahrscheinlich als "packed record" deklariert werden.
Andere Tipps
Sie könnten versuchen, die structQSnap auf einen Zeiger auf diese Struktur typisieren. So etwas wie
PstructVTIQSnap = ^structVTIQSnap;
structVTIQSnap = packed record
bstrSymbol: WideString;
// other stuff...
end;
und
procedure TForm1.HandleVTIQuoteSnap(ASender: TObject;
var structQSnap: OleVariant);
var
ps: PstructVTIQSnap;
symbol: WideString;
begi
ps := PstructVTIQSnap(structQSnap.VPointer^);
symbol := ps.bstrSymbol;
...
end;
Was ich nicht verstehe, aber ist folgendes: Ich nehme es von der ref in der C # -Code, dass die Struktur zweimal rangieren sollte, einmal aus der Bibliothek an die Callback, zweiten zurück in die Bibliothek. Dies würde bedeuten, dass die varByRef Flagge ($ 4000) muss in VType gesetzt werden, aber der Wert, den Sie in Ihrem Kommentar gab (3484) ist viel zu klein?
versuchen zu schauen, was kehrt in TVarData (structQSnap) .VType?
sein kann, wird es funktionieren:
var
symbol: WideString;
rec: structVTIQSnap;
begin
rec := structVTIQSnap(structQSnap);
symbol := rec.bstrSymbol;
end;
Ich bin mir nicht sicher, warum Sie den „structVTIQSnap“ erwägen, ein „OleVariant“ zu sein. Scheint eine ungerade Übersetzung zu mir. Könnte es sein, dass es in ein OleVariant in irgendeiner Form gebracht worden ist, entweder als ein Array oder ähnliches?