读内存 16进制显示(500分)(100分)

  • 主题发起人 主题发起人 未来107
  • 开始时间 开始时间
to 卡色:
怎样在确定pmem的大小(数据已经存在与pmem中了,在dll中开辟了10000个),有没有
刚好读出 pmem大小的函数
 
sizeof()在这个问题中无论怎样取出大小为总是4
 
pMem是一个指针, 它在Win32总是4字节, 如果想得到pMem指向空间的大小, 实际上
在CreateFileMapping已经传进去了, 就是这个参数的值.
 
对了,你的pmem是一个指针,占4个字节,当然sizeof(pmem)为4。
但pmem指向的数据结构是什么呢?

或者你可以在MapFile的数据结构中加一个Size,写入数据时同时写入Size。
 
试试
m := pChar(integer(pmem))
sizeof(m)吧!
 
那只能说明你的程序有问题,
我上面的程序,在读内存前进行赋值,读取的值完全正确!!
 
to 卡色
这样也不行
m := pChar(integer(pmem));
Self.WriteLn(pMem^,sizeof(m));这样只能够取道4个位置。

Self.WriteLn(pMem^,10000);这样只能够取道正取得值(汉字还不行),但是
这样的话当pmem的数据读完了之后,还会读出一些无用字符,pmem的大小<10000

to 卡色,tseug,小小k
现在所有的问题归结到两点:
1、如何确定pmem的大小
2、如何在delphi中真确显示汉字也就是WriteLn怎样修改后可以真确显示汉字。
 
哈哈,,,灌水一下,看到这个题目,我就想起tseug。。。。

果然他在。。。哈哈
 
用 widestring 进行转换!

到底是什么意思?你已经离题万里了!!!!!!!!!!
 
不好意思,的确有点离题了
1、如何确定pmem的大小
用sizeof()好像得不到 pmem文件的大小而是 pointer这个类型所占用的字符大小(4)
2、如何在delphi中真确显示汉字也就是WriteLn怎样修改后可以真确显示汉字。
 
pmem 的大小是由你建立时指定的!!!!!!!

hFileMap:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,memsize,'Share');
//----- 这个就是大小!!!!
你运行了我的程序没有?如果运行了肯定能受到启发!!
 
1.增加一个Size参数或者固定分配内存。
2.和writeln无关。

请三思再提问。
 
to jsxjd
你的程序我已经运行过了,的确一切正常。memsize的确是文件的大小,但是pmem的内容
还不足以填充这个文件的大小(我没有根据内容分配大小),所以我想知道有没有获取这个
pmem大小的函数,如果有困难,这个问题我可以通过在创建映射过程中固定内存分配并传递
大小来实现,谢谢您了!到时候我会另开问题,你来取分!再次谢谢!

To zw84611
不知道怎样才能正确显示汉字(以writeln为例,如何修改)。那个widestring我转换好
像没用!
 
稍微改了一下
procedure TForm1.WriteLn(const Buffer; Count: Integer);
var
P : PByteArray;
B : Byte;
C : Char;
S : String;
I : Integer;
J : Integer;
begin
P := @Buffer;
for I := 0 to (Count+15) div 16 -1 do
begin
S := Format(' %0.8X ', [I*$10]);
for J := 0 to $F do //每行以十六进制数显示16个字节
begin
if I*$10+J < Count then
begin
B := P^[I*$10+J];
if J = 7 then //第8个字符后显示一个分隔符
S := S + IntToHex(B, 2) + '-'
else
S := S + IntToHex(B, 2) + ' ';
end
else
S := S + ' '; //没有数据时以空格填充
end;

J := 0; //显示16个字节对应的字符
while J < $10 do
begin
C := ' '; //空格

if I*$10+J < Count then C := Chr(P^[I*$10+J]);

if isDBCSLeadByte(P^[I*$10+J]) and (I*$10+J+1 < Count) then //汉字
begin
S := S + C;
Inc(J);

C := Chr(P^[I*$10+J]);
S := S + C;
end
else
begin
if (C < ' ') or (C > '~') then C := '.'; //其他不可见字符以"."显示
S := S + C;
end;

Inc(J);
end;

Memo1.Lines.Add(S);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
const MEMSIZE=100;
var
s:string;
hfilemap:hwnd;
pmem:pointer;
p:pchar;
c:char;
i:integer;
begin
hFileMap:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,memsize,'Share');
if hFileMap=0 then
begin
CloseHandle(hFileMap);
ShowMessage('打开内存映射文件错误');
end;
//读取
pmem:=MapViewOfFile(hFileMap,File_Map_All_Access,0,0,0);// 访问整个映象文件
if pMem=nil then
begin
CloseHandle(hFileMap);
UnmapViewOfFile(pMem);
ShowMessage('读取存映射文件错误');
end;

//放一些内容
s := '123456你好, 世界!654321';
Move(S[1], pMem^, Length(s));

////////////////////////////

Self.WriteLn(pMem^, MEMSIZE);

UnmapViewOfFile(pMem);
CloseHandle(hFileMap);
end;
 
谢谢 tseug,谢谢所有的朋友!
最后再问一下,有没有直接取得上面的pmem大小的函数,strlen,sizeof,lentgth无论
我怎样转怎样变都不能取得这个pmem实际的大小。

稍候,我结贴,请tseug,卡色,小小k,jsxjd,zw84611到
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1097601
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1432589
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1404586
发贴,结分
 
谢谢,我就不必了。
 
谢谢你们了
 
谢谢大家
 
后退
顶部