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 如何解释?
pStr := PChar(temp); // 这句话有问题
FileWrite( fh, pStr, 30 );你可以直接
FileWrite( fh, PChar(temp), 30 );
如果声明为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类型的,那么就正确了
打了一大堆,自己看了一下,好像在解释问题,其实是有点越说越糊涂的感觉,不过既然打了,就发吧,无奈了
我只是觉得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最郁闷的地方.
FileWrite(fh,pstr^,30);
StrCopy,它自动将传递array[..] of char的首地址,但是,对于无类型参数的情形,编译器就不能够理解你的意图了,所以PChar和array[..]of char还是严格区分的作为var 无类型参数传递时,传递PChar实际上传递的是^PChar, 传递array[..] of char实际上传递的是数组首地址这个问题我虽然熟悉delphi,我有时也会觉得有点不踏实,你要觉得郁闷,你可以遵循严格的语法,那么你自己就会觉得踏实了比如调用StrCopy时,StrCopy(..., @szSrc[0])