进程间内存共享问题[转]
生活随笔
收集整理的這篇文章主要介紹了
进程间内存共享问题[转]
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
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,找了一些資料,對這個內存共享還不是很了解。但聽同事說在日志管理上還是可以用得上的,特別是多進程間日志管理,這個問題我遇到好久了,就先收集一些文章,到后面再慢慢的學習使用吧。
上面的代碼我還沒有測試過,看了一下,覺得有些錯誤,一會我自己試試,同時對這個內存共享問題也多了解一些。
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,找了一些資料,對這個內存共享還不是很了解。但聽同事說在日志管理上還是可以用得上的,特別是多進程間日志管理,這個問題我遇到好久了,就先收集一些文章,到后面再慢慢的學習使用吧。
上面的代碼我還沒有測試過,看了一下,覺得有些錯誤,一會我自己試試,同時對這個內存共享問題也多了解一些。
轉載于:https://www.cnblogs.com/WuCountry/archive/2006/08/14/476220.html
總結
以上是生活随笔為你收集整理的进程间内存共享问题[转]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java配置文件工具类,java项目加载
- 下一篇: 基4fft算法的蝶形图_原地且自动整序的