Delphi OleVariant来自COM库的字符串数组

EFD*_*EFD 5 delphi string com variant safearray

我有Delphi 2006客户端应用程序.此客户端从COM服务器接收Olevariant类型数据.功能是:

procedure OnLimitsChanged(var SymbolsChanged: {??PSafeArray}OleVariant);
Run Code Online (Sandbox Code Playgroud)

此函数返回一个字符串数组.我无法从delphi中读取OleVariant类型的数据.

从Excel VBA开始工作:

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
Run Code Online (Sandbox Code Playgroud)

我试图将OleVariant转换为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; 
Run Code Online (Sandbox Code Playgroud)

但我收到的除此之外:

 SafeArrayGetLBound(Data,1,iLow);
Run Code Online (Sandbox Code Playgroud)

调试器故障通知
项目...出现错误消息:'0x751de18c处的访问冲突:读取地址0xabababab'.进程停止器.使用"步骤"或"运行"继续

任何建议和意见将不胜感激.

Rem*_*eau 5

RTL 具有从 中正确VarArrayAsPSafeArray()提取 a的功能:PSafeArray(Ole)Variant

procedure TfmConfiguracion.RecibirNuevosTicks(ASender: TObject; var ArrayTicks : OleVariant);    
var 
  Data : PVarArray; // RTL's version of PSafeArray
  //...
begin
  Data := VarArrayAsPSafeArray(ArrayTicks);
  //...
end; 
Run Code Online (Sandbox Code Playgroud)

如果(Ole)Variant不包含数组,则会引发异常。或者您可以使用VarIsArray()手动检查它:

procedure TfmConfiguracion.RecibirNuevosTicks(ASender: TObject; var ArrayTicks : OleVariant);    
var 
  Data : PVarArray;
  //...
begin
  if not VarIsArray(ArrayTicks) then Exit;
  Data := VarArrayAsPSafeArray(ArrayTicks);
  //...
end; 
Run Code Online (Sandbox Code Playgroud)

话虽如此,它(Ole)Variant具有对访问PSafeArray元素数据的内置支持,因此您实际上并不需要PSafeArray直接访问(除非您想要额外的性能提升,在这种情况下,您需要PSafeArray在访问其数据之前验证自己) :

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; 
Run Code Online (Sandbox Code Playgroud)