首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Delphi 7:访问冲突- TByteDynArray问题

Delphi 7:访问冲突- TByteDynArray问题
EN

Stack Overflow用户
提问于 2010-07-01 12:28:18
回答 1查看 3.6K关注 0票数 3

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

代码语言:javascript
运行
复制
  DataPart            = class;             
  Message             = class;             
  eMessage            = class;             

  eventType = ( send, delete, etc );

  DataPart = class(TRemotable)
  private
    FhasData: Boolean;
    Fdata: TByteDynArray;
  published
    property hasData: Boolean read FhasData write FhasData;
    property data: TByteDynArray read Fdata write Fdata;
  end;
  Message = class(TRemotable)
  private
    FMessageID: Int64;
    Ftimestamp: TXSDateTime;
    Fevent: eventType;
    FmagicNumber: WideString;
    FDataPart: DataPart;
  published
    property MessageID: Int64 read FMessageID write FMessageID;
    property timestamp: TXSDateTime read Ftimestamp write Ftimestamp;
    property event: eventType read Fevent write Fevent;
    property magicNumber: WideString read FmagicNumber write FmagicNumber;
    property DataPart: DataPart read FDataPart write FDataPart;
  end;

  eMessage = class(TRemotable)
  private
    FencryptedMessage: TByteDynArray;
    Fdata: DataPart;
  published
    property encryptedMessage: TByteDynArray read FencryptedMessage write FencryptedMessage;
    property data: DataPart read Fdata write Fdata;
  end;

  MyApplicationPortType = interface(IInvokable)
  ['{99767D33-6B4A-7547-4DAC-0608095CAC70}']

    function  sendMessage(const encryptedMessage: TByteDynArray; const data: DataPart): WideString; stdcall;
  end;

有人能用将调用sendMessage()而不导致访问冲突的虚拟值来编写示例吗?我真的不知道如何处理TByteDynArray

按要求编辑,这是我的代码,但是--免责声明--在发布之前,我不得不对它进行大量的黑客攻击(减少),所以它可能无法编译。sendMessage()的两个parms是非空的。

代码语言:javascript
运行
复制
  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);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-07-01 13:29:06

新理念:您在这个单元中有范围检查吗?添加{$R+}

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

在访问每个TByteDynArray的元素之前,不仅必须对其调用TByteDynArray:

代码语言:javascript
运行
复制
SetLength(Fdata, MyDesiredLengthWhichIsGreaterThanZero):

你在这里也要小心,我认为这会给你带来麻烦:

代码语言:javascript
运行
复制
  property data: TByteDynArray read Fdata write Fdata;

你的自动生成器为你做了那个代码,如果你真的知道你想要一个动态数组,你显然可以发布它。(更新:我一开始就错了)。

正如罗布所指出的那样,TRemotable不适用于索引属性,但是可以很好地处理“字节数组”( TByteDynArray )属性,因此,如果一切都做对了,就不需要停止使用TByteDynArray(最初我错了)。

如果是我从头开始写这个,我会使用"string“类型,而不是像TBytes那样。我想知道为什么它不使用TBytes,但我知道您正在使用一些自动生成的WSDL生成器代码来实现SOAP客户机。因此,考虑到这一点,使您的代码不崩溃是非常有可能的。

see also this Related question

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

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

代码语言:javascript
运行
复制
  procedure TestMe( whatever:TWhatever );
  var 
    FData:TByteDynArray;
  begin
     SetLength(FData,2); 
     FData[0] := 10; 
     FData[1] := 20;
     sendMessage(FData, whatever);
  end;
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3157732

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档