function TCommunication.SendDataBuffers(GateIdx: Integer; Gate: pTGateInfo; MsgList: TList): Boolean;
 DataA: PChar;
  DataB: PChar;
  DataC: PChar;
  I: Integer;
  nDataALen: Integer;
  nDataBLen: Integer;
  nDataCLen: Integer; try    I := 0;
    DataA := MsgList.Items[I];
    while (True) do begin
      try
        if (I + 1) >= MsgList.Count then Break;
        DataB := MsgList.Items[I + 1];
        Move(DataA^, nDataALen, SizeOf(Integer));
        Move(DataB^, nDataBLen, SizeOf(Integer));        if (nDataALen + nDataBLen) < g_Config.nBlock then begin
          MsgList.Delete(I + 1);
          GetMem(DataC, nDataALen + SizeOf(Integer) + nDataBLen);
          nDataCLen := nDataALen + nDataBLen;
          Move(nDataCLen, DataC^, SizeOf(Integer));
          Move(DataA[SizeOf(Integer)], PChar(DataC + SizeOf(Integer))^, nDataALen);
          Move(DataB[SizeOf(Integer)], PChar(DataC + nDataALen + SizeOf(Integer))^, nDataBLen);
          FreeMem(DataA);
          FreeMem(DataB);
          DataA := DataC;
          MsgList.Items[I] := DataA;
        end;
说明下这个MsgList它加载的是一个文本文件中的内容(汉字),g_Config.nBlock是Integer类型的它的值是1024
1.Move(DataA^, nDataALen, SizeOf(Integer));从这里我就开始犯迷糊了.
  我个人理解是DataA^从这里移动SizeOf(Integer)这么多字节到nDataALen,但是DataA是PChar类型nDataALen是Integer的,  移 过去之后变成什么东西了?搞不懂
2.if (nDataALen + nDataBLen) < g_Config.nBlock then begin这里他们进行比较,nDataALen和nDataBLen肯定是数值了,   怎么知道他们是多大的数
3.Move(nDataCLen, DataC^, SizeOf(Integer));这句也不太明白
4.Move(DataA[SizeOf(Integer)], PChar(DataC + SizeOf(Integer))^, nDataALen);
  DataA[SizeOf(Integer)]从这个位置开始移动,这个位置内容是什么?这段代码求解释,翻译

解决方案 »

  1.   

    我也觉得Move(DataA^, nDataALen, SizeOf(Integer));这句有问题。。
    不过我可以解释这句:Move(DataA[SizeOf(Integer)], PChar(DataC + SizeOf(Integer))^, nDataALen);其中DataA[SizeOf(Integer)]等价于PChar(Integer(DataA)+Sizeof(Integer))^,即指向地址为Integer(DataA)+Sizeof(Integer)的一个字符
      

  2.   

    dataA dataB的头4个或8个字节是数据长度,这是程序中约定的,所以可以Move4个或8个字节的数据过去。sizeof(integer)=4或8
      

  3.   

    至于nDataALen是不是还要取地址或其它 你自己调试一下
      

  4.   

    ndataAlen := integer(dataA^)大概也行 试试看 不确定
      

  5.   

    1.Move(DataA^, nDataALen, SizeOf(Integer));这里的 nDataALen 是个 integer,因此,第三个参数 SizeOf(Integer) 实际就是 nDataALen 的长度,语句的作用,就我理解:是从 DataA^ 取 4 个字节、放入 nDataALen 。也就是 DataA^ 这里的4个字节按 integer 类型读取,然后“赋值”给nDataALen。
      

  6.   

    从来不确定move里的源和目标参数,哪个在前。。delphi对于指针的用法,有点迁就方便而不够严谨了,如:p^.field1也能写成p.field1
    还有函数的var参数,也会让调用者忘了其实是编译器进行了地址转换
      

  7.   

     nDataALen 是 DataA 的长度,就是说,DataA^ 这里4个字节放着DataA 的长度.   
      

  8.   

    我是这样理解的,不知道会否误导了你:
    try  I := 0;//这变量有点像摆设,它一直没改变。我都不明白为什么要设置这个变量
      DataA := MsgList.Items[I];//取出 MsgList 的第 0 行数据给 DataA 
      while (True) do begin //设置一个死循环
      try
      if (I + 1) >= MsgList.Count then Break; //如果 MsgList 的行数少于等于 1 则不再循环
      DataB := MsgList.Items[I + 1];//取出 MsgList 的第 1 行数据给 DataB
      Move(DataA^, nDataALen, SizeOf(Integer));//从 DataA 头 4 个字节取值给 nDataALen (大概是标志着 DataA 的长度)
      Move(DataB^, nDataBLen, SizeOf(Integer));//参考上一行  if (nDataALen + nDataBLen) < g_Config.nBlock then begin//如果DataA与DataB的和少于1024 
      MsgList.Delete(I + 1);//删除 MsgList 的第 1 行
      GetMem(DataC, nDataALen + SizeOf(Integer) + nDataBLen);//按DataA与DataB的长度+4为长度,分配内存空间给 DataC 
      nDataCLen := nDataALen + nDataBLen;//设置 DataC 的长度为 DataA + DataB 的长度
      Move(nDataCLen, DataC^, SizeOf(Integer));//将 DataC 的长度写入它的头 4 个字节
      //下面的两句,估计第二个参数处有误——用一个 pchar 去加一个整型
      Move(DataA[SizeOf(Integer)], PChar(DataC + SizeOf(Integer))^, nDataALen);
      Move(DataB[SizeOf(Integer)], PChar(DataC + nDataALen + SizeOf(Integer))^, nDataBLen);
      FreeMem(DataA);//释放,下同
      FreeMem(DataB);
      DataA := DataC;//将 DataC 赋值给 DataA
      MsgList.Items[I] := DataA;//将 DataA 写入 MsgList 的第 0 行
      end;
      

  9.   

    这两句没有错的,是我当时没理解过来,现在,我是这样理解这两句话的:
    ......
      Move(nDataCLen, DataC^, SizeOf(Integer));//将 DataC 的长度写入它的头 4 个字节
      Move(DataA[SizeOf(Integer)], PChar(DataC + SizeOf(Integer))^, nDataALen);//在 DataC 的开头 4 个字节后写入 DataA[4] 后的数据 
      Move(DataB[SizeOf(Integer)], PChar(DataC + nDataALen + SizeOf(Integer))^, nDataBLen);//在 DataC 的开头偏移(4 个字节 + DataA[4] 后的数据长度)的位置写入 DataB[4] 起的数据
      FreeMem(DataA);//释放,下同
      ......
    也就是说,DataC 内容是:头 4 个字节是 DataC 数据的长度(不是DataC的长度!),紧接着是 DataA 的数据,最后是 DataB 的数据。 PChar(DataC + SizeOf(Integer))^ ————指 DataC 相对其第一个位置偏移了 SizeOf(Integer) 那么多的一个位置,Move 方法就是将数据在这个位置开始写入的(写入的内容是 DataA[4] 后的数据,长度是 nDataALen 个)。
      

  10.   

    因为 DataC 是 pchar 类型,它本身是个地址,因此,“DataC + SizeOf(Integer)” 就是 DataC 相对其第一个位置的地址偏移了 SizeOf(Integer) 的一个位置(地址)。由于我没受过这专业的教育,很担心自己参与讨论而误导了楼主,很希望懂这方面的朋友来鉴证下我的理解,在此先行谢礼!还望不吝指教。
      

  11.   

    楼主的这段代码应该没有摘录全。这段代码的本意是把相邻的两个节点,如果小于1024字节,就进行合并,我猜测其目的应该是减少交互的次数。其中每个节点都保存的一段数据,其相应的数据结构为 “[长度][数据]”,如果要写成结构体:
    struct tagDataNode{
      int Length;
      unsigned char Data[];
    }DataNode,*LPDataNode;
    LPDataNode = ^DataNode;
    DataNode = packed Record
      Length: Integer;
      Data: array[0..0] of Byte; //这里的下标只是一个形式定义,可以通过动态内存分配指向任意有效长度内存
    end;
      

  12.   


    说的太专业了没明白呀,移动4个字节到目的地,nDataALen他是多大的值呢?DataA[SizeOf(Integer)这个位置是什么呢
      

  13.   

    1.Move(DataA^, nDataALen, SizeOf(Integer));从这里我就开始犯迷糊了.
    这句相当于
    nDataALen := PIneger(DataA)^;
    后者明显高效最好是象unsigned所说,定义一个结构来处理,更好维护.