如何把TList中的内容移到内存中去 ( 积分: 30 )

  • 主题发起人 主题发起人 seeok
  • 开始时间 开始时间
S

seeok

Unregistered / Unconfirmed
GUEST, unregistred user!
假如有个变量UpList类型为TList,存放的是一个结构体;有个指针P为Poniter类型,表示为共享内存区.用Move(UpList,P^,SizeOf(TList))可以把UpList全部放入共享内存区吗?假如我在另一个程序中读这块共享内存去,可不可以读到UpList中存放的结构体?
 
假如有个变量UpList类型为TList,存放的是一个结构体;有个指针P为Poniter类型,表示为共享内存区.用Move(UpList,P^,SizeOf(TList))可以把UpList全部放入共享内存区吗?假如我在另一个程序中读这块共享内存去,可不可以读到UpList中存放的结构体?
 
你这样用SizeOf访问类变量,返回的肯定是4,这怎么可能能做到你想要的效果!
 
不行,你的TList只在你自己EXE程序的线性内存中存在,你的Move是不行的,除非你用另外的格式缓存到内存,你另外一个程序生成同样的TList对象后,再把缓存的数据读回来填充TList里面的值才行.对象是无法用Move函数移动的.
 
楼上的两位老兄,讲的很有道理,能不能举个具体的例子出来啊?谢谢
 
不懂,听听
 
1、对于结构体,假如有如下定义:
type
trMyRecord = packed record
i: integer;
r: real;
end;
var
rec: trMyRecord;
p: Pointer;
begin
GetMem(p, SizeOf(rec))
// 如果这段内存不使用GetMem分配,而是共享内存,例如使用内存映射,那你在其他的进程中也可以访问到这段内存
MoveMemory(p, @rec, SizeOf(rec));
FreeMem(p);
end;
2、对于类,假如有如下定义:
type
trMyClass = class
private
Fi: integer;
Fr: real;
public
function GetData(pBuf: Pointer;const BufSize: Cardinal): Cardinal

end;
function trMyClass.GetData(pBuf: Pointer;const BufSize: Cardinal): Cardinal;
var
p: Pointer;
begin // 在这里我就不判断BufSize的大小是否充足了,你自己添上把
result:= 0;
p:= pBuf;
PInteger(p)^:= Fi;
Inc(p, SizeOf(Fi));
PDouble(p)^:= Fr;
Inc(result, SizeOf(Fi)+SizeOf(Fr));
end;

上面只是举了个例子,对于你使用的TList,他所存储的数据是一系列的指针,这些指针可以指向任何类型,怎么存储,那你得另写个函数了!
我不知道是不是班门弄斧!?热心无罪!
 
TrustMe,非常谢谢你!但是我还想再问一下,就是对于上面的结构体,如何从内存中读到具体的一个结构体中呢?
 
从内存中读数据到结构体:
var
p: Pointer;
rec: trMyRecord;
begin
// p:= 指向内存区域的指针
MoveMemory(@rec, p, SizeOf(rec));
end;

是否符合你需要的答案!?
 
TrustMe,您好,请看一下我下面的代码有没有什么问题,但就是得不到正确的答案.
有结构体如下: TInGoods=Record
ID:Integer;
Remark:String;
end;
Var
p,k:pointer;
InGoods:TInGoods;
Begin
ZeroMemory(@InGoods,SizeOf(TInGoods));
InGoods.ID := 1233;
InGoods.Remark :='test yixia';
p := GetMemory(SizeOf(TInGoods));
move(InGoods,P^,sizeof(InGoods));
k := GetMemory(SizeOf(TInGoods));
move(p^,k^,sizeof(InGoods));
showmessage(TInGoods(p^).Remark);
End;
为什么我showmessage出来的值是空的,而不是test yixia呢,感到很困惑.
 
这种提法本身就有问题,TList的内容难道不在内存中吗?要实现你的想法,其实很容易的,改改你上面的代码就行了:
PInGoods=^TInGoods;
TInGoods=record
ID:Integer;
Remark:String;
end;
.....
var
P: PInGoods
// 声明为全局变量,可以在本进程任何引用此单元的单元中使用
// 如果要跨进程的话,也很容易,但要多做些事情,这里省了。

......
// 在本单元或引用本单元的单元的任意过程中可以访问
showmessage(P^.Remark);

initialization
New(P)
// 在单元初始化段分配内存
P^.ID := 1233
// 赋值
P^.Remark :='test yixia'


finalization
Dispose(P)
// 在单元结束化段释放内存
 
特尔斐,你好,你可能误解我的意思了.我上面写的是一个函数里的一段代码,但我不知道为什么那样是有问题的.
 
有结构体如下: TInGoods=Record
ID:Integer;
//Remark: String;
Remark:array[0..255]of char
// 改这里
end;
Var
p,k:pointer;
InGoods:TInGoods;
Begin
ZeroMemory(@InGoods,SizeOf(TInGoods));
InGoods.ID := 1233;
//InGoods.Remark :='test yixia';
lstrcpy(@InGoods.Remark[0],'test yixia')
// 改这里
p := GetMemory(SizeOf(TInGoods));
move(InGoods,P^,sizeof(InGoods));
k := GetMemory(SizeOf(TInGoods));
move(p^,k^,sizeof(InGoods));
//showmessage(TInGoods(p^).Remark);
MessageBox(GetActiveWindow,@TInGoods(P^).Remark[0],nil,0)
// 这个地方不改也行
End;
 
后退
顶部