gpt4 book ai didi

arrays - Delphi JSONArray SetJSONValue 访问冲突

转载 作者:行者123 更新时间:2023-12-03 15:57:48 27 4
gpt4 key购买 nike

我有一个 JSONArray 作为参数传递到我的服务器。我有一个由“生成 datasnap 客户端类”过程生成的方法,当它到达第一个“SetJsonValue”行时,它给我一个访问冲突,这个错误来来去去,没有明显的原因。我在 LAN 中使用 Rest 服务器(也将其与 http 一起使用,但尚未对其进行测试)。有时它可以通过重新启动我的计算机/编译器来解决,但有时它会持续更长时间。

该方法如下所示:

if FExecutaInsertCommand = nil then
begin
FExecutaInsertCommand := FConnection.CreateCommand;
FExecutaInsertCommand.RequestType := 'POST';
FExecutaInsertCommand.Text := 'TServerMethods."ExecutaInsert"';
FExecutaInsertCommand.Prepare(TServerMethods_ExecutaInsert);
end;
FExecutaInsertCommand.Parameters[0].Value.SetWideString(database);
FExecutaInsertCommand.Parameters[1].Value.SetWideString(Tabela);
FExecutaInsertCommand.Parameters[2].Value.SetJSONValue(aValores, FInstanceOwner);
FExecutaInsertCommand.Parameters[3].Value.SetJSONValue(aTipos, FInstanceOwner);
FExecutaInsertCommand.Parameters[4].Value.SetInt32(usuario);
FExecutaInsertCommand.Execute(ARequestFilter);
Result := FExecutaInsertCommand.Parameters[5].Value.GetInt32;

从这里调用该方法:

result := DMClient.ServerMethodsClient.ExecutaInsert(banco, Tabela, GeraJSONArray(Registro), GeraJSONArray(GetStrings(Registro.DataType)), CodigoUsuarioLogado);

JSONArrays 是这样生成的:

function GeraJSONArray(Valores: TVariantArray) : TJSONArray;
var
i : Integer;
begin
result := TJSONArray.Create;
for i := 0 to Length(Valores.Values) - 1 do
result.Adiciona(Valores.Values[i], Valores.DataType[i]);
end;

function GeraJSONArray(Valores: TArray<String>) : TJSONArray;
var
i : Integer;
begin
result := TJSONArray.Create;
for i := 0 to Length(Valores) - 1 do
result.AddElement(TJSONString.Create(Valores[i]));
end;

JsonArray.Adiciona:

procedure TJSONArrayHelper.Adiciona(valor: variant; DataType: TFieldType);
var
JSONValue : TJSONValue;
begin
if not (VarIsEmpty(valor)) and not (VarIsNull(valor)) then
begin
case DataType of
TFieldType.ftString,
TFieldType.ftMemo,
TFieldType.ftFmtMemo,
TFieldType.ftFixedChar,
TFieldType.ftWideString : JSONValue := TJSONString.Create(valor);
//-----------------------------------------------//
TFieldType.ftSmallint,
TFieldType.ftInteger,
TFieldType.ftWord,
TFieldType.ftFloat,
TFieldType.ftCurrency,
TFieldType.ftAutoInc,
TFieldType.ftLargeint,
TFieldType.ftSingle,
TFieldType.ftBCD : JSONValue := TJSONNumber.Create(valor);
//-----------------------------------------------//
TFieldType.ftDateTime : JSONValue := TJSONString.Create(DateTimeParaString(valor));
end;
end
else
begin
JSONValue := TJSONNull.Create;
end;
if JSONValue <> nil then
AddElement(JSONValue);
end;

参数 2 生成错误,但参数 3 没有,我认为 Adiciona 程序有问题

最佳答案

在您的 Adiciona 中方法,如果 DataType不是您 case 中列出的任何值声明,然后是你本地的JSONValue变量保持未初始化状态。特别要注意的是,变量的默认值是而不是 nil — 本地对象引用变量没有默认值 — 因此您在方法末尾检查 JSONValue <> nil这是无意义的比较。

documentation lists 52 possible TFieldType values ;您的代码只能处理 15。您可以使用 else条款来解释剩下的内容:

case DataType of
...
else raise Exception.CreateFmt('Unexpected field type (%d)', [Ord(DataType)]);

编译器应该警告您该变量可能未初始化,尽管该警告所需的分析不可能完美,因此编译器可能无法检测到这种情况。如果编译器向您发出警告,而您忽略了该警告,那么请将此作为您的一个教训。

向数组添加未初始化的对象引用时我们可能期望的行为与您观察到的访问冲突异常一致。析构函数将从数组中获取未初始化的值并尝试调用 GetOwned在上面。对非对象引用的事物调用方法可能会导致许多问题;您可以期望的最好事情就是您现在所看到的,这是一个异常,立即告诉您出了问题。 (试想一下,如果程序默默地继续运行,情况会有多糟糕。谁知道如果析构函数的 Member.Free 调用已经运行并且实际上破坏了程序中的其他内容,您会看到什么奇怪的问题?)

关于arrays - Delphi JSONArray SetJSONValue 访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33650389/

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