TCommBlock = record   //数据包
                 VAR1 : Smallint ; 
               VAR2 : Real ;
             end;WriteCommBlock.VAR1 := 2 ;
WriteCommBlock.VAR2 := 2000 ;AThread.Connection.WriteBuffer (WriteCommBlock, SizeOf (WriteCommBlock), true);在报文内数据为2 = 02 00,2000 = D0 07
可是实际需要 2 = 00 02,2000= 07 D0
求教如何处理才能满足实际需要

解决方案 »

  1.   

    你这不是取反,而是取的网络字节序或者X86字节序。使用API htons转换。或者:
    function ByteSwap2(value:Word):Word; assembler;
    asm
      BSWAP eax
      shr eax, 16
    end;//function ByteSwap4(value:DWord):DWord; assembler;
    //asm
    //  BSWAP eax
    //end;var
      W:Word;
    begin
      W := 2;
      W := ByteSwap2(W);
    end;
      

  2.   

    使用API htons
    或者
    function ByteSwap2(value:Word):Word; assembler;
    asm
      BSWAP eax
      shr eax, 16
    end;
    均可成功对2字节的数据进行转换但是4字节的无法使用API htons
    function ByteSwap4(value:DWord):DWord; assembler;
    asm
      BSWAP eax
    end;
    使用时会提示invalid floating point operation
      

  3.   

    四字节是:
    htonl取到Invalid floating point operation,是不是你对浮点数进行了换位?
      

  4.   

    ntons/htonl是一个API,在Windows下需要Winsock/Winsock2bswap是一个指令,并非所有CPU都支持,一般在Intel和AMD平台下可以放心使用
      

  5.   

    对于浮点数,是否需要考虑字节序,我一时间也拿不准,浮点数有一个IEEE标准,理论上来说是应该不需要考虑的。建议测试一下,我也去了解一下先。
      

  6.   

    ntohs(network to host short)
    htonl(host to network long)
      

  7.   

    刚才测试了一下,也是需要转换的,不过需要注意的是Real是8字节,而不是4字节(比如Single)
      

  8.   

    需要换序。经过一点小改动后,已经成功。
    function ByteSwap4(value:Single):Single; assembler;
    asm
      MOV EAX,value
      BSWAP EAX
      MOV @result,EAX
    end;可是出现一个新的奇怪现象发送2个Smallint时,长度为4,正常。
    TCommBlock = record  //数据包 
                    VAR1 : Smallint ;  
                  VAR2 : Smallint ; 
                 end; 发送2个Single时,长度为8,也正常。
    TCommBlock = record  //数据包 
                    VAR1 : Single ;  
                  VAR2 : Single ; 
                 end; 
    可是发送一个Smallint和一个Single时,长度是8,而不是2+4=6。
    TCommBlock = record  //数据包 
                    VAR1 : Smallint ;  
                  VAR2 : Single ; 
                 end;
    反复测试后发现,当连续的2个数据为不同类型时,中间会自动插入2个字节。不知为何。
    比如
    TCommBlock = record  //数据包 
                    VAR1 : Smallint ;  
                  VAR2 : Single ; 
                  VAR3 : Smallint ; 
                 end;
    长度为12,而不是2+4+2=8使用的是IdTcpServer的Writebuf方法。
      

  9.   

    //4位Single
    var
      S: Single;
      S1: Single;
      S2: Single;
      dw: Dword;
    begin
      S := 100.5;
      dw := ByteSwap4(PDWord(@S)^);
      S1 := PSingle(@dw)^ ;
      ShowMessage(Format('%f',[S1]));
      dw := ByteSwap4(PDWord(@S1)^);
      S2 := PSingle(@dw)^;
      ShowMessage(Format('%f',[S2]));
    end;//任意位的转换
    procedure SizedByteSwap(value:PChar;Size:Integer);
    var
      S,E: PChar;
      T: Char;
    begin
      if Value = Nil then Exit;
      if Size < 2 then Exit;  S := Value;
      E := PChar(Integer(Value) + Size - 1);
      repeat
        T := E^;
        E^ := S^;
        S^ := T;
        Inc(S);
        Dec(E);
      until (S>=E);
    end;var
      R: Real;begin
      R := 100.5;
      SizedByteSwap(PChar(@R),sizeof(R));
      ShowMessage(Format('%f',[r]));
      SizedByteSwap(PChar(@R),sizeof(R));
      ShowMessage(Format('%f',[r]));
    end;
      

  10.   


    是定义结构的字节对齐问题。Project-Option-Compiler->Code generation->Record field alignment 设成1
    或者定义结构加 packed