我对Delphi相当陌生&必须编写SOAP客户端代码。导入WSDL会生成以下代码(显然我不能更改,因为我显然必须遵守服务器端的要求)
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是非空的。
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);发布于 2010-07-01 13:29:06
新理念:您在这个单元中有范围检查吗?添加{$R+}
如果要使用动态数组类型,则必须在访问构造函数之前在构造函数中明确设置其长度,并且在复制/赋值时也必须非常小心。
在访问每个TByteDynArray的元素之前,不仅必须对其调用TByteDynArray:
SetLength(Fdata, MyDesiredLengthWhichIsGreaterThanZero):你在这里也要小心,我认为这会给你带来麻烦:
property data: TByteDynArray read Fdata write Fdata;你的自动生成器为你做了那个代码,如果你真的知道你想要一个动态数组,你显然可以发布它。(更新:我一开始就错了)。
正如罗布所指出的那样,TRemotable不适用于索引属性,但是可以很好地处理“字节数组”( TByteDynArray )属性,因此,如果一切都做对了,就不需要停止使用TByteDynArray(最初我错了)。
如果是我从头开始写这个,我会使用"string“类型,而不是像TBytes那样。我想知道为什么它不使用TBytes,但我知道您正在使用一些自动生成的WSDL生成器代码来实现SOAP客户机。因此,考虑到这一点,使您的代码不崩溃是非常有可能的。
see also this Related question
我不知道如何编写SOAP客户端,但看起来您的代码做了一些不可靠的事情。看起来,您需要修复您的动态数组处理,包括“呃-哦,您为什么要在这里进行强制转换”问题,Rob向您指出。但是,您似乎也不能随意更改类型,因为看起来您必须使用由TRemotable机制所知道和处理的类型。
至于你的要求,这应该是可行的:
procedure TestMe( whatever:TWhatever );
var
FData:TByteDynArray;
begin
SetLength(FData,2);
FData[0] := 10;
FData[1] := 20;
sendMessage(FData, whatever);
end;https://stackoverflow.com/questions/3157732
复制相似问题