I have Delphi 2006 client application. This client recieves an Olevariant type data from COM server. The function is:
procedure OnLimitsChanged(var SymbolsChanged: {??PSafeArray}OleVariant);
This function returns an array of string. I can´t read OleVariant type data from delphi.
From Excel VBA it´s working:
Private Sub g_Realtime_OnLimitsChanged(SymbolsChanged() As String)
Dim i%
Dim Salir As Boolean
If UBound(SymbolsChanged) <> -1 Then
i = 0: Salir = False
While Not Salir
If SymbolsChanged(i) = Simbolo Then
LlamarALimites
Salir = True
Else
i = i + 1
If i > UBound(SymbolsChanged) Then Salir = True
End If
Wend
End If
End Sub
I tried to convert OleVariant to Psafearray...
procedure TfmConfiguracion.RecibirNuevosTicks(ASender: TObject;
var ArrayTicks : Olevariant);
var
Data : pSafeArray;
i,iLow, iHigh : Integer;
value : wideString;
begin
Data:=PSafeArray(TVarData(ArrayTicks).VArray);
SafeArrayGetLBound(Data,1,iLow);
SafeArrayGetUBound(Data,1,iHigh);
for i:=iLow to iHigh do
begin
SafeArrayGetElement(Data,i,Value);
Showmessage(Value);
end;
But I recieve an except in this line:
SafeArrayGetLBound(Data,1,iLow);
Debugger Fault Notification
Project ... faulted with message: ' access violation at 0x751de18c: read of address 0xabababab'. Process Stopper. Use Step or Run to continue
Any advice and suggestions will be greatly appreciated.
The RTL has a VarArrayAsPSafeArray() function for extracting a PSafeArray correctly from an (Ole)Variant:
procedure TfmConfiguracion.RecibirNuevosTicks(ASender: TObject; var ArrayTicks : OleVariant);
var
Data : PVarArray; // RTL's version of PSafeArray
//...
begin
Data := VarArrayAsPSafeArray(ArrayTicks);
//...
end;
If the (Ole)Variant does not contain an array, an exception will be raised. Or you can use VarIsArray() to check it manually:
procedure TfmConfiguracion.RecibirNuevosTicks(ASender: TObject; var ArrayTicks : OleVariant);
var
Data : PVarArray;
//...
begin
if not VarIsArray(ArrayTicks) then Exit;
Data := VarArrayAsPSafeArray(ArrayTicks);
//...
end;
That being said, (Ole)Variant has build-in support for accessing PSafeArray element data, so you don't really need to resort to accessing PSafeArray directly (unless you want an extra performance boost, in which case you need to validate the PSafeArray yourself before you access its data):
procedure TfmConfiguracion.RecibirNuevosTicks(ASender: TObject; var ArrayTicks : Olevariant);
var
i : Integer;
value : String;
begin
if not VarIsArray(ArrayTicks) then Exit;
for i := VarArrayLowBound(ArrayTicks, 1) to VarArrayHighBound(ArrayTicks, 1) do
begin
Value := ArrayTicks[i];
ShowMessage(Value);
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With