Delphi XE2 里面string 与 ansistring 转换导致kbmMW 的一个bug

简介: 昨天本来准备写一个kbmMW 做webserver 的一个例子,可是在调试过程中发现不能正常显示图片文件。跟踪了很长时间 才发现是string 和 ansistring 在XE2 里面转换造成的问题,经过修改后,终于可以正常运行了。

    昨天本来准备写一个kbmMW 做webserver 的一个例子,可是在调试过程中发现不能正常显示图片文件。跟踪了很长时间

才发现是string 和 ansistring 在XE2 里面转换造成的问题,经过修改后,终于可以正常运行了。耽搁了半天时间,因此记录一下,

给同学们一个参考,以后在编程时注意一下。

  原来的程序代码是这样的:

procedure TkbmMWAJAXResponseTransportStream.InternalDeliver(const AInfo:IkbmMWCustomTransportInfo);
var
i,j,k:integer;
s,sr:string; // 注意,这一块原来定义的是string;
ba:TkbmMWBytes;
hlp,hlpReq:TkbmMWHTTPTransportStreamHelper;
begin
hlp:=TkbmMWHTTPTransportStreamHelper(Helper);
hlpReq:=TkbmMWHTTPTransportStreamHelper(RequestTransportStream.Helper);

// Make sure we respond using same version as using for request.
hlp.HTTPVersion:=hlpReq.HTTPVersion;

// Check if to deliver XML Response or not.
if not (Params.Values[KBMMW_AJAX_PARAMS_XMLRESPONSE]='1') then
begin
// Check which HTTP header to send.
if Self.IsError then
begin
MimeType:='text/html';
s:=hlp.HTTPBuildErrorResponseHeaderFromStatusCode('',TkbmMWAJAXTransportStreamHelper(Helper).Header,
Self.StatusCode,Self.StatusText);
kbmMWDebugDumpString(mwdlAdvanced,mwdtTransport,kbmMWDebugWhere,'AJAX Response deliver HTML body',s);

AInfo.CloseConnectionAfterTransmit:=true;

ba:=kbmMWString2Bytes(AnsiString(s));
TProtTransport(Transport).DoTransmitBuffer(AInfo,ba,length(ba));
end
else
begin
// If the result is an array, the first element is the header instead of us generating one.
if not VarIsArray(Result) then
begin
// Send ok response with data.
sr:=Result; // result 原来的值是ansistring, 现在转换成string 类型了
s:=hlp.HTTPBuildOKResponseHeader('',TkbmMWAJAXTransportStreamHelper(Helper).Header,length(sr))+sr; // length(sr) 是unicodestring 的长度,理论上<= ansistring 的值,因此封装是就使用了一个

// 一个错误的content-length, 导致客户端与服务器端的数据不一致。
ba:=kbmMWString2Bytes(AnsiString(s));
kbmMWDebugDumpString(mwdlAdvanced,mwdtTransport,kbmMWDebugWhere,'AJAX Response deliver HTML',s);
TProtTransport(Transport).DoTransmitBuffer(AInfo,ba,length(ba));

下面是修改后的代码:

procedure TkbmMWAJAXResponseTransportStream.InternalDeliver(const AInfo:IkbmMWCustomTransportInfo);
var
i,j,k:integer;
s,sr:ansistring; // 这一块使用ansistgring, 与原始的数据类型保持一致
ba:TkbmMWBytes;
hlp,hlpReq:TkbmMWHTTPTransportStreamHelper;
begin
hlp:=TkbmMWHTTPTransportStreamHelper(Helper);
hlpReq:=TkbmMWHTTPTransportStreamHelper(RequestTransportStream.Helper);

// Make sure we respond using same version as using for request.
hlp.HTTPVersion:=hlpReq.HTTPVersion;

// Check if to deliver XML Response or not.
if not (Params.Values[KBMMW_AJAX_PARAMS_XMLRESPONSE]='1') then
begin
// Check which HTTP header to send.
if Self.IsError then
begin
MimeType:='text/html';
s:=hlp.HTTPBuildErrorResponseHeaderFromStatusCode('',TkbmMWAJAXTransportStreamHelper(Helper).Header,
Self.StatusCode,Self.StatusText);
kbmMWDebugDumpString(mwdlAdvanced,mwdtTransport,kbmMWDebugWhere,'AJAX Response deliver HTML body',s);

AInfo.CloseConnectionAfterTransmit:=true;

ba:=kbmMWString2Bytes(AnsiString(s));
TProtTransport(Transport).DoTransmitBuffer(AInfo,ba,length(ba));
end
else
begin
// If the result is an array, the first element is the header instead of us generating one.
if not VarIsArray(Result) then
begin
// Send ok response with data.
sr:=Result;
s:=hlp.HTTPBuildOKResponseHeader('',TkbmMWAJAXTransportStreamHelper(Helper).Header,length(sr))
//hlp.HTTPBuildOKResponseHeader 返回的是string, 而且是纯英文的,转换成ansistrng, 不会丢失数据。同时后面不能加sr, 不然的话,会把sr 又转换成string 了, 再转会到 ansistring, 就丢东西了

s:=s+sr; // 两个ansistring 相加, 保证数据类型一致,不产生隐形变换。
ba:=kbmMWString2Bytes(s);


经过上面修改,系统可以正常在XE2 下运行了。当然在d2007 以前,原来的代码没有问题的,看来作者没有在d2009 以后的版本没有好好测试。

好隐蔽的bug, 浪费了我好几个小时。 特记之。

目录
相关文章
|
XML 数据格式
hutool将XML文档转换为String
hutool将XML文档转换为String
Java基础String,int,Integer类型的互相转换
Java基础String,int,Integer类型的互相转换
Java基础String,int,Integer类型的互相转换
|
JavaScript Java 数据库
UTF-8 GBK UTF8 GB2312之间的区别和关系,Java中String和byte[]间的转换,byte 是怎样转为汉字,汉字转byte的;char与
UTF-8 GBK UTF8 GB2312之间的区别和关系,Java中String和byte[]间的转换,byte 是怎样转为汉字,汉字转byte的;char与
364 0
UTF-8 GBK UTF8 GB2312之间的区别和关系,Java中String和byte[]间的转换,byte 是怎样转为汉字,汉字转byte的;char与
|
Java Linux Go
知识分享之Golang——常用的类型转换int、string、float互相转换
知识分享之Golang篇是我在日常使用Golang时学习到的各种各样的知识的记录,将其整理出来以文章的形式分享给大家,来进行共同学习。欢迎大家进行持续关注。 知识分享系列目前包含Java、Golang、Linux、Docker等等。
190 0
知识分享之Golang——常用的类型转换int、string、float互相转换
|
JSON 小程序 PHP
解决php无法将string转换为json的办法
解决php无法将string转换为json的办法
199 0
解决php无法将string转换为json的办法
|
Java
Java:String和List互相转换
Java:String和List互相转换
112 0
|
机器学习/深度学习 SDN C语言
C/CPP中int和string的互相转换详解与多解例题分析
C标准库atoi, atof, atol, atoll(C++11标准) 函数,以及sprintf、sscanf函数,用sstream类,实现C++中int和string的互相转换
237 0
C/CPP中int和string的互相转换详解与多解例题分析
|
Java
Java中StringBuilder与String的互相转换
Java中StringBuilder与String的互相转换
772 0