代码的目的,是将接收过来的 字符串l_Rev复制到 结构体TFusionRec ,进而获取结构体每个成员变量(nFiberType和nTimeSec) 的值。
//定义一个结构体
type
    PFusionRec = ^TFusionRec;
    TFusionRec = packed Record
    nFiberType :Integer;
    nTimeSec :Integer;
  end;
//应用部分
var
  pFusion :PFusionRec;//定义一个结构体指针
  strDisplay:string;
begin
  New(pFusion);
  try
 if l_icount >=132 then
 begin
      CopyMemory(@pFusion,@l_Rev,l_icount);
          strDisplay := '熔接时间:'+ IntToStr(pFusion^.nFiberType)
              + '; 熔接模式:'+ IntToStr(pFusion^.nTimeSec);
    l_icount := 0;
    mem_RevData.Lines.Add(IntToStr(pFusion^.nFiberType));//mem_RevData是Tmemo控件名
 end;  finally
    Dispose(pFusion);
  end;
end;
一切错误的根源是:CopyMemory(@pFusion,@l_Rev,l_icount);
1、若用CopyMemory(@pFusion,@l_Rev,l_icount); 跟踪调试 数据pFusion^.nFiberType及pFusion^.nTimeSec均是正确的,但是执行后会报错
2、若用CopyMemory(pFusion,@l_Rev,l_icount);不会报错,但是数据pFusion^.nFiberType及pFusion^.nTimeSec均不正确,是随机值,达不到要求。请大侠指点,在此表示感谢!

解决方案 »

  1.   

    或许您需要更加了解VCL架构。@pFusion这只是一个指针的地址,而不是对象内存的起始地址。
    没仔细看您的代码,仅供参考。
      

  2.   

    请问楼上大侠,CopyMemory(@pFusion,@l_Rev,l_icount);
    这个应该怎么改?谢谢!
      

  3.   


      New(pFusion);
      Showmessage(Format('%x,%x,%x',[Integer(@pFusion),Integer(pFusion),Integer(@pFusion.nFiberType)]));
      

  4.   

    CopyMemory(@pFusion......
    把pFusion前面的@去掉试试?我不确定,没仔细研究搭车求解决我的问题......
    http://bbs.csdn.net/topics/390445211
      

  5.   

    把字符串复制到结构体,这问题本来就莫名其妙。
    这个字符串l_Rev是什么内容,结构体内的两个integer类型成员各是什么含义
      

  6.   

    procedure CopyMemory(Destination: Pointer; Source: Pointer; Length: DWORD);CopyMemory(@pFusion,@l_Rev,l_icount);1. CopyMemory的前两个参数都是指针,你“pFusion :PFusionRec;//定义一个结构体指针”,所以第一个参数前不用@;2. 从你的代码中判断“if l_icount >=132 then”;也就是说l_icount的长度肯定是超过131的,
    type
        PFusionRec = ^TFusionRec;
        TFusionRec = packed Record
        nFiberType :Integer;
        nTimeSec :Integer;
      end;
    你定义的TFusionRec才站8个Byte,而你却拷贝了至少131个字符到里面,肯定会触发访问非法内存的错误!!!修改: CopyMemory(pFusion,@l_Rev,SizeOf(pFusion));
      

  7.   

    谢谢楼上 大侠们的解答。
    首先,这个结构体 我只是 写了其中两个字段,其余的没写,一共是132个字节,这个可以确定,而且已经验证过了。
    其次,我在第二条说过,如果去掉@,变成CopyMemory(pFusion,@l_Rev,l_icount);这样是不会报错,但是显示的数据pFusion^.nFiberType及pFusion^.nTimeSec均不正确,是随机值。
    所以请各位大侠们帮忙解释下。
    最后,这个l_Rev字符串是 接收过来的串,一共是132个字节,这个也已经验证过。我的意思是:将接收过来的 132个串,通过 COPYMEMORY函数 复制到 指定的 一个结构体中。
    还请各位大侠们 多多指点,谢谢!
      

  8.   

    若l_Rev是一个string,那么它的字符序列的起始地址应该是@l_Rev[1],而不是@l_Rev。
    @l_Rev仍然是一个指针的地址。在这方面Delphi与C是不同的。CopyMemory(pFusion,@l_Rev[1],l_icount);只要地址和长度正确,再精心考虑对象的引用计数(如果需要),CopyMemory覆写对象内存是可以的,这种尝试说明你已具备一定功力。不错!
      

  9.   

    先用一个中间可变记录过渡:TFusionTmp = record
    case integer of
    0:(f1:string(6),f2:string(8),...);//也是132个字节
    1:(s:string(132));
    end;var
    tmp:TFusionTmp;
    tmp.s:=I_rev;
    然后取出f1,f2,..的值就是了
      

  10.   

    或许这样写更明显:
    CopyMemory(@pFusion.nFiberType, @I_Rev[1], I_icount);
    前两个参数分别是目标内存序列的起始地址,和来源内存序列的起始地址。总之就是要绕过类对象的变量名(其实是一个指针)。