进程间内存共享问题[转]
http://www.vkfz.com/net-CreateFileMapping-t55403.htm
playroc 发表于 2006-2-27 23:21:08
超级难题:.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
{
public int EmployeeNo;
public float Salary;
};
Money[] g_Money = new Money[100];
for(int i = 0; i < 100; i++)
{
g_Money[i] = new Money();
g_Money[i].EmployeeNo = i;
g_Money[i].Salary = i*i;
}
try
{
IntPtr memoryFileHandle = CreateFileMapping(0xFFFFFFFF,IntPtr.Zero,(uint)4,0,(uint)(100*8),"SHARE_MEMORY");
if(memoryFileHandle == IntPtr.Zero)
{
MessageBox.Show("Create Share Memory Failed!");
return;
}
g_hMoney = MapViewOfFile(memoryFileHandle,(uint)983071,0,0,(uint)(100*8));
if(g_hMoney == IntPtr.Zero)
{
MessageBox.Show("Create Share Memory Failed!");
return;
}
int basePos = g_hMoney.ToInt32();
for(int j = 0; j < 100; j++)
{
//我现在的做法,每次将数组对象g_Money一个一个的复制到内存中去
Marshal.StructureToPtr(g_Money[j], (IntPtr)(basePos + j * 8), true);
//我现在的做法,每次将内存中的数据复制到数组对象g_Money中
// g_Money[j] = (Money)Marshal.PtrToStructure((IntPtr)(basePos + j * 8), typeof(Money));
}
}
catch(System.Exception exception)
{
MessageBox.Show(exception.Message);
}
我想要得到的效果就是:只要访问g_Money数组就可以直接访问内存,象VC中一样,不要每次对g_Money赋值后再调用Marshal.StructureToPtr修改内存,而每次内存修改后又用Marshal.StructureToPtr读取内存到g_Money来
============================
看了一些API,找了一些资料,对这个内存共享还不是很了解。但听同事说在日志管理上还是可以用得上的,特别是多进程间日志管理,这个问题我遇到好久了,就先收集一些文章,到后面再慢慢的学习使用吧。
上面的代码我还没有测试过,看了一下,觉得有些错误,一会我自己试试,同时对这个内存共享问题也多了解一些。
.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
{
public int EmployeeNo;
public float Salary;
};
Money[] g_Money = new Money[100];
for(int i = 0; i < 100; i++)
{
g_Money[i] = new Money();
g_Money[i].EmployeeNo = i;
g_Money[i].Salary = i*i;
}
try
{
IntPtr memoryFileHandle = CreateFileMapping(0xFFFFFFFF,IntPtr.Zero,(uint)4,0,(uint)(100*8),"SHARE_MEMORY");
if(memoryFileHandle == IntPtr.Zero)
{
MessageBox.Show("Create Share Memory Failed!");
return;
}
g_hMoney = MapViewOfFile(memoryFileHandle,(uint)983071,0,0,(uint)(100*8));
if(g_hMoney == IntPtr.Zero)
{
MessageBox.Show("Create Share Memory Failed!");
return;
}
int basePos = g_hMoney.ToInt32();
for(int j = 0; j < 100; j++)
{
//我现在的做法,每次将数组对象g_Money一个一个的复制到内存中去
Marshal.StructureToPtr(g_Money[j], (IntPtr)(basePos + j * 8), true);
//我现在的做法,每次将内存中的数据复制到数组对象g_Money中
// g_Money[j] = (Money)Marshal.PtrToStructure((IntPtr)(basePos + j * 8), typeof(Money));
}
}
catch(System.Exception exception)
{
MessageBox.Show(exception.Message);
}
我想要得到的效果就是:只要访问g_Money数组就可以直接访问内存,象VC中一样,不要每次对g_Money赋值后再调用Marshal.StructureToPtr修改内存,而每次内存修改后又用Marshal.StructureToPtr读取内存到g_Money来
============================
看了一些API,找了一些资料,对这个内存共享还不是很了解。但听同事说在日志管理上还是可以用得上的,特别是多进程间日志管理,这个问题我遇到好久了,就先收集一些文章,到后面再慢慢的学习使用吧。
上面的代码我还没有测试过,看了一下,觉得有些错误,一会我自己试试,同时对这个内存共享问题也多了解一些。
================================
/\_/\
(=^o^=) Wu.Country@侠缘
(~)@(~) 一辈子,用心做一件事!
--------------------------------
学而不思则罔,思而不学则怠!
================================
/\_/\
(=^o^=) Wu.Country@侠缘
(~)@(~) 一辈子,用心做一件事!
--------------------------------
学而不思则罔,思而不学则怠!
================================
posted on 2006-08-14 11:22 Wu.Country@侠缘 阅读(719) 评论(0) 编辑 收藏 举报