Delphi 2010 PChar 的奇怪现象

ker0 2010-03-04 10:25:35
 MessageBox(0,PChar('L'),PChar('LL'),0);

结果:PChar('LL') 显示 ,但PChar('L') 不显示.


var
p1, p2: PChar;
begin
p1 := PChar('L');
p2 := PChar('LL');
MessageBox(0, p1, p2, 0);
end;

将pp添加到watch list ,发现 p1=''(异常) ,p2='LL'(正常);

疑惑的结论:对于长度为1的字符串,用pchar强制转换,会出错???


...全文
840 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
twins7713 2011-07-28
  • 打赏
  • 举报
回复
求分,呵呵。
qkhhxkj102 2010-03-24
  • 打赏
  • 举报
回复
有的时候不能直接赋值吧
huangheguyun 2010-03-24
  • 打赏
  • 举报
回复
9楼Avan_Lau的解释是合理的。
sy_100000 2010-03-23
  • 打赏
  • 举报
回复
这个问题应该算Pascal的一个经典问题:字符和字符串没有严格区分开,一个字符的字符串就是字符。

比如:'LL'就是字符串,而'L'就是字符。也就是说,一个长度的字符,Pascal默认作为一个字符处理,而不作为字符串处理。所以PChar(字符)就要出问题。


你可以这样测试下:

1、MessageBox(0, 'LL', 'L', 0); 象这样的字符串常量,是不用PChar的;

2、MessageBox(0, PChar('LL'), PChar(string('L')), 0);用string把'L'字符强制指定为字符串。
jingzu 2010-03-08
  • 打赏
  • 举报
回复
PChar是pwidechar指针 应该分配内存才能使用吧。
jingzu 2010-03-08
  • 打赏
  • 举报
回复
PChar是字符串指针,应该分配内存才能使用吧。
huangheguyun 2010-03-05
  • 打赏
  • 举报
回复
支持wzwcn的说法,直接赋值是会申请内存的
ok1411 2010-03-05
  • 打赏
  • 举报
回复
学习了。。。。。。。。。。。。。
ker0 2010-03-05
  • 打赏
  • 举报
回复
强制编译器把单字符解释为PAnsiChar指针:
除"PChar('L'#0)"这样外,


有开关指令吗?
dj2437 2010-03-05
  • 打赏
  • 举报
回复
PChar是单字符指针吧,好像研究过一些时间,BYTE是字节PChar后把STRING转成一个个的字符
ker0 2010-03-04
  • 打赏
  • 举报
回复
问题是目标参数接收的是一个起始地址,如果传过去一个立即数,肯定要出错的.

这样的用法只是在自己程序中处理时可能快一些,如果调用函数的话,有太多的不确定因素了.危险!

而且其帮助文件中也没有说明

[edit] Description
Defines a null-terminated string.
金卯刀 2010-03-04
  • 打赏
  • 举报
回复
是不是bug,我覺得不好界定。
把單個字符處理成立即數給寄存器,效率會比較高。只是看我們怎么用了。
ker0 2010-03-04
  • 打赏
  • 举报
回复
难道是我发现了VCL的Bug
金卯刀 2010-03-04
  • 打赏
  • 举报
回复
剛在D5下測試,單個字符PCHAR也會出問題,調用messagebox會出現地址錯誤,當再加一個字符就不會了。
看來是跟“當為單個字符時,被處理為ASCII,作為立即數”,導致MessageBox無法理解,所造成的。
跟API是否為UNICODE版本無關
金卯刀 2010-03-04
  • 打赏
  • 举报
回复
我大概知道怎么回事了,
請看:
PChar('N') ------匯編$0000004e --- ASCII 78
pchar('L')-------匯編$0000004c --- ASCII 76
可看出:當為單個字符時,被處理為ASCII,作為立即數;
而D2009以上API調用默認為unicode版本,所以....
當PCHAR轉換多個字符時,編譯器把它作為常量,直接取字串所在地址,然后move內容,如:
p2 := pchar('LL')
---- move edx $00484620 //這是LL所在地址
這樣,messagebox就能順利接收字串了,因為LL內容還是unicode的。
ker0 2010-03-04
  • 打赏
  • 举报
回复
var
s1,s2: string;
begin
 s1 := 'W';
s2:='WW';

MessageBox(0, PChar(s1), PChar(s2), 0);
end;

这样调用结果也是正确的.
现在看来只有在 PChar('L') 时会出错
wzwcn 2010-03-04
  • 打赏
  • 举报
回复
MessageBox(0, 'abc', 'abc', MB_OK);
这样调D会自己认为'abc'是pchar的,如果这样,则要把String转成Pchar:
var a,b:String;
begin
a:='abc';
b:='ddd';
MessageBox(0,pchar(a),pchar(b),MB_OK);
end;

虽然知道这样,但是不清楚为什么
MessageBox(0,pchar('L')....
这样单个字符会出错,看汇编不太懂,也希望有高手能解答
ker0 2010-03-04
  • 打赏
  • 举报
回复
欧,原来对于 PChar类型的函数参数 也可以直接赋值 String 呀:)
wzwcn 2010-03-04
  • 打赏
  • 举报
回复
这样可以啊:
My_Msg('LL','L');

或者直接这样:
MessageBox(0, 'abc', 'abc', MB_OK);
ker0 2010-03-04
  • 打赏
  • 举报
回复
坐等高人说法~~~


to:wzwcn

如果这样呢:
procedure My_Msg(pTitle,pText:PChar);
begin
MessageBox(0, pText, pTitle, 0);
end;

var
p1, p2: PChar;
begin
p1 := 'L';
p2 := 'LL';

My_Msg(PChar('LL'),PChar('L')); //出错. 这样多简洁,但会出错.不办法只能用p1,p2来变通.
 My_Msg(p2,p1); // 正确,但啰嗦,要额外申请变量.

end;
加载更多回复(4)

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧