Making Easy

Easymakingmoneysecret Sv Tag Money Easy Making Money Secret 超级难题:.net 中CreateFileMapping 创建共享内存问题 - .NET技术 / C#

Easymakingmoneysecret Sv Tag Money Easy Making Money Secret

  • search Money Easymakingmoneysecret
  • searchsearchsearch Tag Money search
  • searchsearch
  • 解锁
  • 移动
  • 编辑
  • 删除
  • 帖子加分
  • 帖子高亮
  • 取消高亮
  • 结  帖
  • 发  帖
  • 回  复
  • 收藏 超级难题:.net 中CreateFileMapping 创建共享内存问题[问题点数:100,自动结帖]

    • playroc
    • (dullboy)
    • 等 级:
    • 结帖率:
    楼主发表于:2006-02-27 23:19:46
    超级难题:.net   中CreateFileMapping   创建共享内存问题

    .net中可以通过InteropServices调用unmanaged库的方法CreateFileMapping等来创建和使用共享内存。但是如何将一个对象数组对应到创建的内存块呢?这样一来,内存创建后就不用管了,只要对对象数组进行操作就可以了,请高手指点。

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    #region   非托管函数声明
    [DllImport( "kernel32.dll ",EntryPoint= "OpenFileMapping ",SetLastError=true,   CharSet=CharSet.Auto)   ]
    private   static   extern   IntPtr   OpenFileMapping   (int   dwDesiredAccess,   bool   bInheritHandle,String   lpName   );

    [DllImport( "Kernel32.dll ",EntryPoint= "CreateFileMapping ",SetLastError=true,CharSet=CharSet.Auto)]
    private   static   extern   IntPtr   CreateFileMapping(uint   hFile,   IntPtr   lpAttributes,   uint   flProtect,uint   dwMaximumSizeHigh,   uint   dwMaximumSizeLow,   string   lpName);

    [DllImport( "Kernel32.dll ")]
    private   static   extern   IntPtr   MapViewOfFile(IntPtr   hFileMappingObject,uint   dwDesiredAccess,   uint   dwFileOffsetHigh,uint   dwFileOffsetLow,   uint   dwNumberOfBytesToMap);

    [DllImport( "Kernel32.dll ",EntryPoint= "UnmapViewOfFile ",SetLastError=true,CharSet=CharSet.Auto)]
    private   static   extern   bool   UnmapViewOfFile(IntPtr   lpBaseAddress);

    [DllImport( "kernel32.dll ",EntryPoint= "CloseHandle ",SetLastError=true,CharSet=CharSet.Auto)]
    private   static   extern   bool   CloseHandle(uint   hHandle);

    [DllImport( "kernel32.dll ",EntryPoint= "GetLastError ",SetLastError=true,CharSet=CharSet.Auto)]
    private   static   extern   uint   GetLastError();
    #endregion


    struct   Money
    {};


    Money[]   g_Money   =   new   Money[100];
    for(int   i   =   0;   i   <   100;   i++)
    {}

    try
    {}

    g_hMoney   =   MapViewOfFile(memoryFileHandle,(uint)983071,0,0,(uint)(100*8));  
    if(g_hMoney   ==   IntPtr.Zero)
    {}

    int   basePos   =   g_hMoney.ToInt32();
    for(int   j   =   0;   j   <   100;   j++)
    {}
    }
    catch(System.Exception   exception)
    {}

    我想要得到的效果就是:只要访问g_Money数组就可以直接访问内存,象VC中一样,不要每次对g_Money赋值后再调用Marshal.StructureToPtr修改内存,而每次内存修改后又用Marshal.StructureToPtr读取内存到g_Money来

    回复次数:4
    #1楼 得分:0回复于:2006-02-27 23:47:37
    You   can   not   do   that   unless   use   unmanaged   C++   code.   Managed   Objects   are   located   on   local   managed   heaps.
    • The123
    • (Shall We Dance?)
    • 等 级:
    #2楼 得分:0回复于:2006-02-28 00:31:48
    只要访问g_Money数组就可以直接访问内存

    using   System;

    class   a
    {};

    static   unsafe   void   Main(string[]   args)
    {}
      fixed(Money*   m   =g_Money)
    {}          
    }
    }
    #3楼 得分:0回复于:2006-03-01 08:25:18
    感谢jiangsheng和The123的回复!

    The123,我想说的是只要访问g_Money数组就可以直接访问我前面创建的内存,也就是要把g_Money数组和先前创建的共享内存对应起来
    • The123
    • (Shall We Dance?)
    • 等 级:
    #4楼 得分:0回复于:2006-03-01 16:18:20
    不可以。传统的(怎么觉得这么别扭)或者说非托管的c/c++里对内存你可以“指哪打哪”,托管的(c#)你不能那么随便了,内存的使用微软的公共语言运行库   (CLR)给你“托管”了。
    你那个Money数组跑在CLR给你“托管”了的内存上,所以你不可能像通常一样直接映射到“调用unmanaged库的方法CreateFileMapping等来创建和使用共享内存”那部分的内存,你也只能通过Marshal.StructureToPtr,Marshal.PtrToStructure的方式来“映射”。
    如果你不是对速度要求特别苛刻的话是没必要用你上面的方式的,你可以把你要操作的数组定义成一个全局变量就可以了。