var
  pStr   : PChar;
  buffer : array[0..500] of char;
  temp   : string;
begin
  temp := object.Name; // 返回某个对象的名称,该对象名称为固长30,用string存储
  pStr := PChar(temp);
  FileWrite( fh, pStr, 30 );
 . ......
end;
  比如oject.Name为'adfadsfasdfasdfasdfasdfasdf'等.则写进去的东西,全为乱码
将程序改为
begin
   temp := object.Name; 
  StrCopy(buffer, PChar(temp) );
  FileWrite( fh, buffer, 30 ); // ok!!
  ......
end;FileWrite的函数声明为: 
function FileWrite( fh : Integer; const : buffer; count : Integer ) : Integer;问题:PChar和字符串数组不一样??!!!!既然都可以解析成指针.为什么,使用字符串指针就不行了?
     这显然不是惯用法.
     const 如何解释?

解决方案 »

  1.   

    temp := object.Name; // 返回某个对象的名称,该对象名称为固长30,用string存储
      pStr := PChar(temp); // 这句话有问题
      FileWrite( fh, pStr, 30 );你可以直接
      FileWrite( fh, PChar(temp), 30 );
      

  2.   

    常见的错误,也是语言中比较晦涩的地方,很多人都问过了function FileWrite( fh : Integer; const buffer; count : Integer ) : Integer;的const表示无类型参数,函数内不能变
    如果声明为var buffer;则为函数内可变,都是没有声明类型的对于这种参数,当你传递参数时,实际上传递了参数的指针,
    而在带这种声明的函数的实现内部,参数的语义不变,也就是你传递的是什么,在函数内这个参数代表的就是什么看FileWrite的实现function FileWrite(Handle: Integer; const Buffer; Count: LongWord): Integer;
    begin
    {$IFDEF MSWINDOWS}
      if not WriteFile(THandle(Handle), Buffer, Count, LongWord(Result), nil) then
        Result := -1;
    {$ENDIF}
    ...buffer又传递给系统API writefile了,注意了,恰好WriteFile中的buffer的原型也是无类型的,所以直接传递bufferOk, 你暂时已经知道"当你传递参数时,实际上传递了参数的指针"了
    现在,这样来看这种参数声明法,打个比方说,当你传递PChar类型参数时,实际调用的函数原型是function FileWrite(Handle: Integer; const Buffer: ^PChar; Count: LongWord): Integer;也就是function FileWrite(Handle: Integer; const Buffer: PPChar; Count: LongWord): Integer;那么
    实际执行的是if not WriteFile(THandle(Handle), Buffer^, Count, LongWord(Result), nil) then
    这时,WriteFile的Buffer参数为PChar类型,但是因为WriteFile本身的Buffer参数也是untyped的,所以,编译出来的结果实际上是又传递了^PChar,即PPChar,显然,参数错了而当你传递的是array[0..100] of char类型的实参时,实际调用的函数原型是
    function FileWrite(Handle: Integer; const Buffer: ^(array[0..100] of char); Count: LongWord): Integer;也就是
    type
      t0_100char = array[0..100] of char;
      p0_100char = ^t0_100char;function FileWrite(Handle: Integer; const Buffer: p0_100char; Count: LongWord): Integer;实际执行,
    if not WriteFile(THandle(Handle), Buffer^, Count, LongWord(Result), nil) then
    即WriteFile的Buffer类型为t0_100char
    又因前面说了writefile的buffer也是untyped的,所以在传递给writefile时,实际传递给这个windows api的是p0_100char类型的,那么就正确了
    打了一大堆,自己看了一下,好像在解释问题,其实是有点越说越糊涂的感觉,不过既然打了,就发吧,无奈了
      

  3.   

    alphax(割禾青) 说了这么多,还是不明白.
    我只是觉得PChar和array[0..80] of char,在delphi中都解析为指针.比如: 
    var
      szSrc : array[0..80] of char;szSrc := 'asdfasdf';
    StrCopy( szDst, szSrc);szSrc在这函数里不是和PChar匹配的吗?
    关于这点,<c++ primer>里面有详细的论述,关于类型匹配的规则.
    真不知道delphi的类型匹配规则如何?
    这是学delphi最郁闷的地方.
      

  4.   

    haha.....
    FileWrite(fh,pstr^,30);
      

  5.   

    >我只是觉得PChar和array[0..80] of char,在delphi中都解析为指针.不对,要看上下文,很多情况下,编译器能够理解你的意图,象你举的例子
    StrCopy,它自动将传递array[..] of char的首地址,但是,对于无类型参数的情形,编译器就不能够理解你的意图了,所以PChar和array[..]of char还是严格区分的作为var 无类型参数传递时,传递PChar实际上传递的是^PChar, 传递array[..] of char实际上传递的是数组首地址这个问题我虽然熟悉delphi,我有时也会觉得有点不踏实,你要觉得郁闷,你可以遵循严格的语法,那么你自己就会觉得踏实了比如调用StrCopy时,StrCopy(..., @szSrc[0])
      

  6.   

    主要原因就是字符串,Pchar都要以\0结束,否则就不知道那里结束了。
      

  7.   

    谢谢alphax(豪言壮语的乌鸦).delphi再搞段时间吧,以后就不做了.