Delphi 7:访问冲突-TByterray问题

Delphi 7:访问冲突-TByterray问题,delphi,Delphi,我对Delphi相当陌生&必须编写一个SOAP客户端。导入WSDL会生成此代码(我显然不能更改此代码,因为我必须遵守服务器端的要求) 有谁能给我编写一个使用伪值的示例,该伪值将调用sendMessage(),并且不会导致访问冲突?我真的不知道如何处理TByterray [编辑]根据要求,这是我的代码,但是-免责声明-在发布之前,我不得不对其进行大量修改(减少),因此它可能无法编译。sendMessage()的两个参数均为非null var theMessageArray: TByteDyn

我对Delphi相当陌生&必须编写一个SOAP客户端。导入WSDL会生成此代码(我显然不能更改此代码,因为我必须遵守服务器端的要求)

有谁能给我编写一个使用伪值的示例,该伪值将调用sendMessage(),并且不会导致访问冲突?我真的不知道如何处理TByterray


[编辑]根据要求,这是我的代码,但是-免责声明-在发布之前,我不得不对其进行大量修改(减少),因此它可能无法编译。sendMessage()的两个参数均为非null

  var theMessageArray: TByteDynArray;
      theResult : WideString;
      messageData : TByteDynArray;
      i : Integer;
begin
  theMessage.messageID := theMessage.messageID + 1;
  theMessage.timestamp := TXSDateTime.Create();
  theMessage.timestamp.AsDateTime := Now();
  theMessage.event := delete;
  theMessage.magicNumber  := 'magic # ' + IntToStr(theMessage.messageID);

  SetLength(messageData, 1);
  messageData[0] := 0;

  theMessage.dataPart.hasData := True;
  messageData := theMessage.dataPart.messageData;

  SetLength(messageData, $1000 * dataSize);

  for i := 0 to $1000 * dataSize - 1 do
        messageData[i] := i and $FF;

  theMessage.DataPart.messageData := messageData;

  theMessageArray := TByteDynArray(theMessage);
  theResult := (HTTPRIO1 as MyApplicationPortType).sendMessage(theMessageArray, theMessage.dataPart);

新想法:您在本单元中有范围检查吗?添加{$R+}

如果要使用动态数组类型,必须在访问它之前在构造函数中明确设置其长度,并且在复制/赋值时也必须非常小心

在访问每个TByteDnArray元素之前,不仅必须调用SetLength:

SetLength(Fdata, MyDesiredLengthWhichIsGreaterThanZero):
你在这里也必须小心,我认为这会给你带来麻烦:

  property data: TByteDynArray read Fdata write Fdata;
你的自动生成器为你编写了代码,如果你真的知道你想要一个动态数组,你显然可以发布它。(更新:最初我错了)

正如Rob所指出的,TRemotable不适用于索引属性,但适用于“字节数组”(TByteDynArray)属性,因此,如果一切正常,就不需要停止使用TByteDynArray(一开始我是错的)

如果是我从头开始写的话,我会使用“string”类型,比如TBytes。我想知道为什么它没有使用TBytes,但我知道您正在使用一些自动生成的WSDL生成器代码实现一个SOAP客户机。因此,考虑到这一点,使您的代码不崩溃应该是完全可能的

我不知道如何编写SOAP客户端,但您的代码似乎做了一些不可靠的事情。看起来您需要修复动态数组处理,包括Rob向您指出的“哦,为什么要在这里进行转换”问题。但是,看起来您也不能随意更改类型,因为您必须使用由您的可转机制知道并处理的类型

至于你的要求,这应该是可行的:

  procedure TestMe( whatever:TWhatever );
  var 
    FData:TByteDynArray;
  begin
     SetLength(FData,2); 
     FData[0] := 10; 
     FData[1] := 20;
     sendMessage(FData, whatever);
  end;

这只是一个接口。你在做什么导致访问冲突?+1是一个好问题。有两种方法可以解决这个问题-向您展示我的代码并找出它不起作用的原因,或者有人发布一些起作用的代码&我可以将其与我自己的代码进行比较。好的,我会发布我的代码,但重要的是(我认为)两个参数在调用时都是非空的。你真的是在从胜利的口中夺取失败,因为你使用了tbytednarray而不仅仅是TBytes(实际上只是一个字符串)。什么版本的delphi?请更新(重新标记)。AV源可能是这样的:
theMessageArray:=TBytednarray(theMessage)变量不是动态数组;类型转换不能使它成为一个。分配将尝试增加假定数组的refcount,它甚至可以在不崩溃的情况下运行。之后,
sendMessage
尝试将该内存当作数组使用。它读取“长度”,并尝试访问那么多字节。该长度不能准确反映有多少字节,或者refcount修改可能会破坏内存。经验法则:如果你输入一个动态数组,就有问题了。谢谢,沃伦(+1)。我刚刚发布了我的代码(删除了很多不相关的东西)。是的,我设定了长度。我可以编写Get/Set(),但不能直接访问属性吗?(告诉你我是Delphi新手)你没有设置fdata的长度。您认为SetLength(SomethingElse,10)然后分配fdata=somthingelse会起作用,但它不会起作用。我认为您建议的修复方法与TRemotable不兼容。数组需要在类中定义,以便TRemotables的使用者知道如何获取数组的全部内容。对于数组属性,这是不可能发生的(因为使用者不知道有效的索引值是什么)。如果您使用的是为您生成的自动生成代码,则必须在错误时对其进行更改。请参阅我喜欢的相关问题:设置本地
messageData
变量的长度,然后将其分配给dynamic array属性似乎是正确的做法。将一个动态数组分配给另一个动态数组是完全安全的。引用计数得到更新,因此数组将保持活动状态,直到所有人都使用完它。我认为其根源可能在于确定
sendMessage
函数希望接收的字节数组。那么,Mawg,什么是MyApplicationPortType,您应该给它什么样的加密消息?
  procedure TestMe( whatever:TWhatever );
  var 
    FData:TByteDynArray;
  begin
     SetLength(FData,2); 
     FData[0] := 10; 
     FData[1] := 20;
     sendMessage(FData, whatever);
  end;