我在一个ocx中创建了一个共享内存,结构如下:
const MEM_FILENAME = 'share_memory';
type
  TShared = packed record
    ID: array[0..255] of Integer;
    PathList: array[0..255, 0..255] of char;
  end;
  PShared = ^TShared;
创建并打开共享共享内存后,
  Shared^.ID[0] := 1029;
  str := pchar('D:\Program Files\vss\win32\SSEXP.EXE');
  CopyMemory(@(Shared^.PathList[0]), str, length(str));
然后在一个dll中也打开并读取该共享内存
 HShareMap := OpenFileMapping(FILE_MAP_WRITE, False, pchar(MEM_FILENAME));  Shared := PShared(MapViewOfFile(HShareMap, FILE_MAP_ALL_ACCESS, 0, 0, 0));
  len := length(Shared^.ID);  for I := 0 to len - 1 do
  begin    if (Shared^.ID[I] <>0) or (Shared^.PathList[I]<>'') then
    begin
      showmessage('Shared^.ID['+ inttostr(I) + ']:::' + inttostr(Shared^.ID[I]));
      showmessage('Shared^.PathList['+ inttostr(I) + ']:::' + strpas(Shared^.PathList[I]));
    end;  end;
按理说我是在数组的第0个位置写入数据的,然后应该在第0个位置读取到才对啊
结果发现第0个位置ID确实有个数值,但并不是我要的1029,而是别的数值,第0个位置的path是空的
第2个位置的ID是空的,而第2个位置的path是我存进去的'D:\Program Files\vss\win32\SSEXP.EXE'
第128位ID值是1029,第128位置的Path是空的。
不解了,为什么下标都乱了呢?
是我共享内存定义的不对吗?还是我写入或者读取的不对?

解决方案 »

  1.   

    共享内存就这么些代码了啊,再全就是把创建写出来了
      //打开或者创建内存共享文件
      HShareMap := OpenFileMapping(FILE_MAP_WRITE, False, pchar(MEM_FILENAME));
      if HShareMap = 0 then
      begin
        HShareMap := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
          SizeOf(TShared), pchar(MEM_FILENAME));
      end;  Shared := PShared(MapViewOfFile(HShareMap, File_MAP_WRITE, 0, 0, 0));
      

  2.   

    CopyMemory(@(Shared^.PathList[0][0]), str, length(str));
    改成试试?
      

  3.   

    这个肯定不行了,因为那个是二维数组。Shared^.PathList[0][0]只能代表第一个pchar数据里的第一个字符。
      

  4.   

    监视目标程序启动并记录下来相关信息。
    Activex创建共享内存,并向共享内存数组中写入一些需要监控的程序路径;
    DLL监视程序启动,当发现程序启动时,就拿着程序路径与共享内存中的路径数组比较,判断是否在监控范围内,如果是在监控范围内,则记录日志这个Acitvex放在网页上,必须先从网页登录监管系统,然后才开始启动监控。
      

  5.   

    那你的TShared 结构有否说明一下.
      

  6.   

    type 
      TShared = packed record 
        ID: array[0..255] of Integer; //需要被监控的程序在数据库里的ID,主键,将来出审计日志,要以此为索引
        PathList: array[0..255, 0..255] of char; //需要被监控的程序路径
      end; 
      PShared = ^TShared;
      

  7.   

    packed record 
    这么写,据说如果用在Dll里,应该这么写。否则可能会导致内存中分配长度有问题。
      

  8.   

    个人建议你把结构的定义改一下也许会更方便一点
    type
      TFilePathString = String[256];  TShared = packed Record
        ID: array [0..255] of Integer;
        PathList: Array[0..255] of TFilePathString;
      end;
      

  9.   

    个人建议你把结构的定义改一下也许会更方便一点 
    type 
      TFilePathString = String[256];   TShared = packed Record 
        ID: array [0..255] of Integer; 
        PathList: Array[0..255] of TFilePathString; 
      end;
    同意楼上的
      

  10.   

    const MEM_FILENAME = 'share_memory';
    type
      TShared =packed record
        ID: array[0..255] of Integer;
        PathList: array[0..255,0..255] of char;
      end;
      PShared = ^TShared;
    var
      Shared:PShared;
      str:pchar;
      HShareMap:DWORD;
    begin
      HShareMap := CreateFileMapping($FFFFFFFF , nil, PAGE_READWRITE, 0,SizeOf(TShared), MEM_FILENAME);
      Shared:=MapViewOfFile(HShareMap, File_MAP_WRITE, 0, 0, SizeOf(TShared));
      Shared^.ID[0] := 1029;
      str := Pchar('D:\Program Files\vss\win32\SSEXP.EXE');
      CopyMemory(@Shared^.PathList[0],str,length(str));
      UnMapViewOfFile(Shared);
      Shared:=nil;
      HShareMap:=0;  HShareMap := CreateFileMapping($FFFFFFFF , nil, PAGE_READONLY, 0,SizeOf(TShared), MEM_FILENAME);
      Shared := MapViewOfFile(HShareMap, FILE_MAP_READ, 0, 0, SizeOf(TShared));
      ShowMessage(Shared^.PathList[0]);
    end;
      

  11.   

    to ideation_shang :
       我在ActiveX写共享内存的过程里写完共享内存后,直接查看共享内存内容的时候,也是对的。
       只是在Dll里再Open并读取的时候,顺序就错了。
       你现在是在同一个过程里,两次Create,能解释下原因吗?谢谢
      

  12.   

    尝试了僵哥的建议,竟然顺序都对了。
    但还是想不明白其中道理,为什么我用二维char数组就不行呢?
    难道共享内存对二维支持有问题?
    僵哥能再帮忙解释下吗?我更想知道其中道理,否则以后我迟到还是会卡在这里的(被同一块石头绊倒两次)。
      

  13.   

    二维char数组,是一个表格,那样子你就需要很清楚其内存布局,否则操作就会存在问题.