我有 Delphi 2006 客户端应用程序。该客户端从 COM 服务器接收 Olevariant 类型数据。其功能是:
procedure OnLimitsChanged(var SymbolsChanged: {??PSafeArray}OleVariant);
该函数返回一个字符串数组。我无法从 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
我尝试将 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;
但是我在这一行收到一个异常(exception):
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
如有任何意见和建议,我们将不胜感激。
最佳答案
RTL 有一个 VarArrayAsPSafeArray()
函数,用于从 (Ole)Variant
中正确提取 PSafeArray
:
procedure TfmConfiguracion.RecibirNuevosTicks(ASender: TObject; var ArrayTicks : OleVariant);
var
Data : PVarArray; // RTL's version of PSafeArray
//...
begin
Data := VarArrayAsPSafeArray(ArrayTicks);
//...
end;
如果(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;
话虽这么说,(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;
关于string - Delphi OleVariant 到 COM 库中的字符串数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30441967/