zoukankan      html  css  js  c++  java
  • Delphi XE2 里面string 与 ansistring 转换导致kbmMW 的一个bug

        昨天本来准备写一个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, 浪费了我好几个小时。 特记之。

  • 相关阅读:
    Ubuntu14.04+cuda 7.5+cudnn_v4+tensorflow安装
    error C2275: “XXX”: 将此类型用作表达式非法
    DLL调试方法
    OpenCV ——双线性插值(Bilinear interpolation)
    OpenCV ——背景建模之CodeBook(2)
    OpenCV ——背景建模之CodeBook(1)
    OpenCV——GMM混合高斯模型
    OpenCV——运用于pixels war游戏
    【SpringSecurityOAuth2】源码分析@EnableOAuth2Sso在Spring Security OAuth2 SSO单点登录场景下的作用
    【Spring】简述@Configuration配置类注册BeanDefinition到Spring容器的过程
  • 原文地址:https://www.cnblogs.com/xalion/p/2337860.html
Copyright © 2011-2022 走看看