gpt4 book ai didi

arrays - 如何使用 OmniThreadLibrary 中的 SetParameter 将数组作为参数传递给任务?

转载 作者:行者123 更新时间:2023-12-03 19:51:06 28 4
gpt4 key购买 nike

在 Delphi XE8 中,我试图将数组传递给 SetParameter 中的 OTL 任务来自 OmniThreadLibrary:

implementation

type
TCookie = record
Name: string;
Value: string;
ExpDate: string;
ModDate: string;
end;

TCookieArray = array of TCookie;

var
CurCookies: TCookieArray;

procedure TForm1.btnStartTaskClick(Sender: TObject);
begin
SetLength(CurCookies, 2);
CurCookies[0].Name := 'username';
CurCookies[0].Value := 'Paul';
CurCookies[1].Name := 'password';
CurCookies[1].Value := 'none';

FGetCookieDetailsTask := CreateTask(GetCookieEntries, 'GetCookieEntries')
.MonitorWith(OTLMonitor)
// Compiler complaint:
.SetParameter('CookiesArray', TOmniValue.FromArray<TCookieArray>(CurCookies))
.Run;
end;

编译器提示 SetParameter 行:
[dcc32 Error] Unit1.pas(310): E2010 Incompatible types:
'System.TArray<Unit1.TCookieArray>' and 'TCookieArray'

不幸的是,OTL 书中没有关于如何使用 FromArray 的示例。在 SetParameter将数组传递给任务。

那么如何做到这一点呢?

编辑 : ba__friend 要求我在他的回答的评论中显示我的解决方案的源代码:
  FGetCookieDetailsTask := CreateTask(GetCookieEntries, 'GetCookieEntries')
.MonitorWith(OTLMonitor)
// Now no compiler complaint:
.SetParameter('CookiesArray', CurCookies)
.Run;

procedure GetCookieEntries(const task: IOmniTask);
var
TaskCookies, HostCookies: TCookieArray;
begin
HostCookies := task.Param['CookiesArray'];
TaskCookies := Copy(HostCookies, 0, Length(HostCookies));

最佳答案

您的代码中有两个问题。

1) TCookieArray必须声明为

TCookieArray = TArray<TCookie>;

从编译器的角度来看, array of TTArray<T> (可悲)不是一回事。

2) FromArray<T>需要类型 T成为数组项类型,而不是数组类型(参见 OtlCommon ),因此您必须将其从
TOmniValue.FromArray<TCookieArray>


TOmniValue.FromArray<TCookie>

要从任务访问此数组,请调用:
var
cookies: TCookieArray;

cookies := task.Param['CookiesArray'].ToArray<TCookie>;

旁注:事情应该这样工作。然而,在 OTL 直到(包括)3.04b 中,记录类型在 ToArray<T> 中没有被正确处理。和 FromArray<T> .刚刚提交给 GitHub 的修复程序.

如果要手动修复副本,则需要进行两项修改。

TOmniValue.CastFrom<T> , 这个 block
if ds = 0 then // complicated stuff
{$IFDEF OTL_ERTTI}

应该改为
if ds = 0 then // complicated stuff
if ti^.Kind = tkRecord then
Result.SetAsRecord(CreateAutoDestroyObject(
TOmniRecordWrapper<T>.Create(value)))
else
{$IFDEF OTL_ERTTI}

TOmniValue.CastTo<T> , 后面的 block
if ds = 0 then // complicated stuff
{$IFDEF OTL_ERTTI}

应该改为
if ds = 0 then // complicated stuff
if ti.Kind = tkRecord then
Result := TOmniRecordWrapper<T>(CastToRecord.Value).Value
else
{$IFDEF OTL_ERTTI}

关于arrays - 如何使用 OmniThreadLibrary 中的 SetParameter 将数组作为参数传递给任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32287818/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com