有关强制类型转换,请进!(50分)

  • 主题发起人 主题发起人 Jhdandcl
  • 开始时间 开始时间
J

Jhdandcl

Unregistered / Unconfirmed
GUEST, unregistred user!
有2个记录:

Type
TWMCommand = packed record
Msg: Cardinal;
ItemID: Word;
NotifyCode: Word;
Ctl: HWND;
Result: Longint;
end;

TMessage = packed record
Msg: Cardinal;
case Integer of
0: (
WParam: Longint;
LParam: Longint;
Result: Longint);
1: (
WParamLo: Word;
WParamHi: Word;
LParamLo: Word;
LParamHi: Word;
ResultLo: Word;
ResultHi: Word);
end;

var
tm : TWMcommand;
tm1: TMessage

..........
tm. Msg := ...
tm. ItemID:= ...
tm.NotifyCode := ...
tm. Ctl:=
tm. Result:= ..
showmessage(inttostr( Tmessage(tm).wpram ))
...... 为什么正确 ?

请详细说名记录类型强制转换的条件》


 
这个不是什么希奇的事儿。长的记录可以Type成小的,不会出现非法内存访问,反之不行。
自己看看Typecasts就知道了。
 
Delphi显然对基本类型(包括Record)之间的强制类型转换没有设立关卡——也没有必要;
但是,对Class就不一样了,如果你把一个ClassA的对象强制转换为ClassB类型(它们之间没有继承关系),
肯定会出错。
 
有继承关系的class一般都可以cast,其实基本类型就是几个字节而已,在汇编级别的话其实
都没什么区别,大家都是字节
 

===> 长的记录可以Type成小的,不会出现非法内存访问,反之不行。



TYPE
RECOR1 = PACKED RECORD
A :int64 // 8 个Byte.
B :byte // 1 个Byte.
END;
RECOR2 = PACKED RECORD
C :integer // 4 个Byte.
END.

显然 SIZEOF(RECOR1) > SIZEOF(RECOR2) .
But ,
var
x := RECOR1;
begin
x.a := 100;
x.b := 100;
showmessage(inttostr(RECOR2(x).c))
//错!





 
要变体记录~~~~~~~~~
 
奥!还是错了,必须市长度相等的才可以Type?
明白了,原来必须长度相等,实际上上面的两个消息结构是一样的,只不过变成不同字段
原来的是一个DWord,后面的分别取高低Word而已~~~~~~~~~~~~
 
还是不太明白!
 
OK,就是说,长度相等的才可以进行转换!实际上,TWMCommand 和TMessage 是一模一样的两个记录!
只不过字段的类型不一样而已。
对比一下(相同的我不罗嗦):
TWMCommand = packed record
Msg: Cardinal
///相同
ItemID: Word
///Word,两个字节
NotifyCode: Word
///Word,两个字节
Ctl: HWND
///Dword,32Bits
Result: Longint
///Dword,四个字节,32Bit
end;
再来看看
TMessage = packed record
Msg: Cardinal
///相同
case Integer of ///0和1中间,最大长度者作为内存分配依据
0: (
WParam: Longint
///dword,32bits,相当于ItemID和NotifyCode
LParam: Longint
///dword,32Bits
Result: Longint)
///相同
1: (
WParamLo: Word
///WParamLo和WParamHi只不过是分开了WParam的
WParamHi: Word
///高低字节而已。其他的类似。
LParamLo: Word;
LParamHi: Word;
ResultLo: Word;
ResultHi: Word);
end;
所以,可以看出,总长度是一样的,实际上是一样的,经过测试,发现长度相同的记录是可以
互相Type的,先前我的说法有错误,很抱歉。
 
接受答案了.
 
后退
顶部