共享内存操作类(C#源码)
VC++的共享内存操作代码实现起来相对比较容易,但是用C#语言来实现,就有一定难度,由于工作需要,把以前VC开发的共享内存代码要用C#实现,别说,还费了不少周折,毕竟C#操作API函数和地址指针不是那么直接,还好,总算完成了,效果还不错。
共享内存操作类:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.Runtime.InteropServices;
namespaceShareMemLib
{
publicclassShareMem
{
[DllImport("user32.dll",CharSet=CharSet.Auto)]
publicstaticexternIntPtrSendMessage(IntPtrhWnd,intMsg,intwParam,IntPtrlParam);
[DllImport("Kernel32.dll",CharSet=CharSet.Auto)]
publicstaticexternIntPtrCreateFileMapping(inthFile,IntPtrlpAttributes,uintflProtect,uintdwMaxSizeHi,uintdwMaxSizeLow,stringlpName);
[DllImport("Kernel32.dll",CharSet=CharSet.Auto)]
publicstaticexternIntPtrOpenFileMapping(intdwDesiredAccess,[MarshalAs(UnmanagedType.Bool)]boolbInheritHandle,stringlpName);
[DllImport("Kernel32.dll",CharSet=CharSet.Auto)]
publicstaticexternIntPtrMapViewOfFile(IntPtrhFileMapping,uintdwDesiredAccess,uintdwFileOffsetHigh,uintdwFileOffsetLow,uintdwNumberOfBytesToMap);
[DllImport("Kernel32.dll",CharSet=CharSet.Auto)]
publicstaticexternboolUnmapViewOfFile(IntPtrpvBaseAddress);
[DllImport("Kernel32.dll",CharSet=CharSet.Auto)]
publicstaticexternboolCloseHandle(IntPtrhandle);
[DllImport("kernel32",EntryPoint="GetLastError")]
publicstaticexternintGetLastError();
constintERROR_ALREADY_EXISTS=183;
constintFILE_MAP_COPY=0x0001;
constintFILE_MAP_WRITE=0x0002;
constintFILE_MAP_READ=0x0004;
constintFILE_MAP_ALL_ACCESS=0x0002|0x0004;
constintPAGE_READONLY=0x02;
constintPAGE_READWRITE=0x04;
constintPAGE_WRITECOPY=0x08;
constintPAGE_EXECUTE=0x10;
constintPAGE_EXECUTE_READ=0x20;
constintPAGE_EXECUTE_READWRITE=0x40;
constintSEC_COMMIT=0x8000000;
constintSEC_IMAGE=0x1000000;
constintSEC_NOCACHE=0x10000000;
constintSEC_RESERVE=0x4000000;
constintINVALID_HANDLE_VALUE=-1;
IntPtrm_hSharedMemoryFile=IntPtr.Zero;
IntPtrm_pwData=IntPtr.Zero;
boolm_bAlreadyExist=false;
boolm_bInit=false;
longm_MemSize=0;
publicShareMem()
{
}
~ShareMem()
{
Close();
}
///<summary>
///初始化共享内存
///</summary>
///<paramname="strName">共享内存名称</param>
///<paramname="lngSize">共享内存大小</param>
///<returns></returns>
publicintInit(stringstrName,longlngSize)
{
if(lngSize<=0||lngSize>0x00800000)lngSize=0x00800000;
m_MemSize=lngSize;
if(strName.Length>0)
{
//创建内存共享体(INVALID_HANDLE_VALUE)
m_hSharedMemoryFile=CreateFileMapping(INVALID_HANDLE_VALUE,IntPtr.Zero,(uint)PAGE_READWRITE,0,(uint)lngSize,strName);
if(m_hSharedMemoryFile==IntPtr.Zero)
{
m_bAlreadyExist=false;
m_bInit=false;
return2;//创建共享体失败
}
else
{
if(GetLastError()==ERROR_ALREADY_EXISTS)//已经创建
{
m_bAlreadyExist=true;
}
else//新创建
{
m_bAlreadyExist=false;
}
}
//---------------------------------------
//创建内存映射
m_pwData=MapViewOfFile(m_hSharedMemoryFile,FILE_MAP_WRITE,0,0,(uint)lngSize);
if(m_pwData==IntPtr.Zero)
{
m_bInit=false;
CloseHandle(m_hSharedMemoryFile);
return3;//创建内存映射失败
}
else
{
m_bInit=true;
if(m_bAlreadyExist==false)
{
//初始化
}
}
//----------------------------------------
}
else
{
return1;//参数错误
}
return0;//创建成功
}
///<summary>
///关闭共享内存
///</summary>
publicvoidClose()
{
if(m_bInit)
{
UnmapViewOfFile(m_pwData);
CloseHandle(m_hSharedMemoryFile);
}
}
///<summary>
///读数据
///</summary>
///<paramname="bytData">数据</param>
///<paramname="lngAddr">起始地址</param>
///<paramname="lngSize">个数</param>
///<returns></returns>
publicintRead(refbyte[]bytData,intlngAddr,intlngSize)
{
if(lngAddr+lngSize>m_MemSize)return2;//超出数据区
if(m_bInit)
{
Marshal.Copy(m_pwData,bytData,lngAddr,lngSize);
}
else
{
return1;//共享内存未初始化
}
return0;//读成功
}
///<summary>
///写数据
///</summary>
///<paramname="bytData">数据</param>
///<paramname="lngAddr">起始地址</param>
///<paramname="lngSize">个数</param>
///<returns></returns>
publicintWrite(byte[]bytData,intlngAddr,intlngSize)
{
if(lngAddr+lngSize>m_MemSize)return2;//超出数据区
if(m_bInit)
{
Marshal.Copy(bytData,lngAddr,m_pwData,lngSize);
}
else
{
return1;//共享内存未初始化
}
return0;//写成功
}
}
}
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.Runtime.InteropServices;
namespaceShareMemLib
{
publicclassShareMem
{
[DllImport("user32.dll",CharSet=CharSet.Auto)]
publicstaticexternIntPtrSendMessage(IntPtrhWnd,intMsg,intwParam,IntPtrlParam);
[DllImport("Kernel32.dll",CharSet=CharSet.Auto)]
publicstaticexternIntPtrCreateFileMapping(inthFile,IntPtrlpAttributes,uintflProtect,uintdwMaxSizeHi,uintdwMaxSizeLow,stringlpName);
[DllImport("Kernel32.dll",CharSet=CharSet.Auto)]
publicstaticexternIntPtrOpenFileMapping(intdwDesiredAccess,[MarshalAs(UnmanagedType.Bool)]boolbInheritHandle,stringlpName);
[DllImport("Kernel32.dll",CharSet=CharSet.Auto)]
publicstaticexternIntPtrMapViewOfFile(IntPtrhFileMapping,uintdwDesiredAccess,uintdwFileOffsetHigh,uintdwFileOffsetLow,uintdwNumberOfBytesToMap);
[DllImport("Kernel32.dll",CharSet=CharSet.Auto)]
publicstaticexternboolUnmapViewOfFile(IntPtrpvBaseAddress);
[DllImport("Kernel32.dll",CharSet=CharSet.Auto)]
publicstaticexternboolCloseHandle(IntPtrhandle);
[DllImport("kernel32",EntryPoint="GetLastError")]
publicstaticexternintGetLastError();
constintERROR_ALREADY_EXISTS=183;
constintFILE_MAP_COPY=0x0001;
constintFILE_MAP_WRITE=0x0002;
constintFILE_MAP_READ=0x0004;
constintFILE_MAP_ALL_ACCESS=0x0002|0x0004;
constintPAGE_READONLY=0x02;
constintPAGE_READWRITE=0x04;
constintPAGE_WRITECOPY=0x08;
constintPAGE_EXECUTE=0x10;
constintPAGE_EXECUTE_READ=0x20;
constintPAGE_EXECUTE_READWRITE=0x40;
constintSEC_COMMIT=0x8000000;
constintSEC_IMAGE=0x1000000;
constintSEC_NOCACHE=0x10000000;
constintSEC_RESERVE=0x4000000;
constintINVALID_HANDLE_VALUE=-1;
IntPtrm_hSharedMemoryFile=IntPtr.Zero;
IntPtrm_pwData=IntPtr.Zero;
boolm_bAlreadyExist=false;
boolm_bInit=false;
longm_MemSize=0;
publicShareMem()
{
}
~ShareMem()
{
Close();
}
///<summary>
///初始化共享内存
///</summary>
///<paramname="strName">共享内存名称</param>
///<paramname="lngSize">共享内存大小</param>
///<returns></returns>
publicintInit(stringstrName,longlngSize)
{
if(lngSize<=0||lngSize>0x00800000)lngSize=0x00800000;
m_MemSize=lngSize;
if(strName.Length>0)
{
//创建内存共享体(INVALID_HANDLE_VALUE)
m_hSharedMemoryFile=CreateFileMapping(INVALID_HANDLE_VALUE,IntPtr.Zero,(uint)PAGE_READWRITE,0,(uint)lngSize,strName);
if(m_hSharedMemoryFile==IntPtr.Zero)
{
m_bAlreadyExist=false;
m_bInit=false;
return2;//创建共享体失败
}
else
{
if(GetLastError()==ERROR_ALREADY_EXISTS)//已经创建
{
m_bAlreadyExist=true;
}
else//新创建
{
m_bAlreadyExist=false;
}
}
//---------------------------------------
//创建内存映射
m_pwData=MapViewOfFile(m_hSharedMemoryFile,FILE_MAP_WRITE,0,0,(uint)lngSize);
if(m_pwData==IntPtr.Zero)
{
m_bInit=false;
CloseHandle(m_hSharedMemoryFile);
return3;//创建内存映射失败
}
else
{
m_bInit=true;
if(m_bAlreadyExist==false)
{
//初始化
}
}
//----------------------------------------
}
else
{
return1;//参数错误
}
return0;//创建成功
}
///<summary>
///关闭共享内存
///</summary>
publicvoidClose()
{
if(m_bInit)
{
UnmapViewOfFile(m_pwData);
CloseHandle(m_hSharedMemoryFile);
}
}
///<summary>
///读数据
///</summary>
///<paramname="bytData">数据</param>
///<paramname="lngAddr">起始地址</param>
///<paramname="lngSize">个数</param>
///<returns></returns>
publicintRead(refbyte[]bytData,intlngAddr,intlngSize)
{
if(lngAddr+lngSize>m_MemSize)return2;//超出数据区
if(m_bInit)
{
Marshal.Copy(m_pwData,bytData,lngAddr,lngSize);
}
else
{
return1;//共享内存未初始化
}
return0;//读成功
}
///<summary>
///写数据
///</summary>
///<paramname="bytData">数据</param>
///<paramname="lngAddr">起始地址</param>
///<paramname="lngSize">个数</param>
///<returns></returns>
publicintWrite(byte[]bytData,intlngAddr,intlngSize)
{
if(lngAddr+lngSize>m_MemSize)return2;//超出数据区
if(m_bInit)
{
Marshal.Copy(bytData,lngAddr,m_pwData,lngSize);
}
else
{
return1;//共享内存未初始化
}
return0;//写成功
}
}
}
测试例程:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Text;
usingSystem.Windows.Forms;
usingShareMemLib;
namespaceYFShareMem
{
publicpartialclassfrmShareMem:Form
{
ShareMemMemDB=newShareMem();
publicfrmShareMem()
{
InitializeComponent();
}
privatevoidbtnOpen_Click(objectsender,EventArgse)
{
if(MemDB.Init("YFMemTest",10240)!=0)
{
//初始化失败
MessageBox.Show("初始化失败");
}
else
{
btnOpen.Enabled=false;
chkWrite.Enabled=true;
tmrTime.Enabled=true;
}
}
privatevoidtmrTime_Tick(objectsender,EventArgse)
{
byte[]bytData=newbyte[16];
intintRet=MemDB.Read(refbytData,0,16);
lstData.Items.Clear();
if(intRet==0)
{
for(inti=0;i<16;i++)
{
lstData.Items.Add(bytData[i].ToString());
}
if(chkWrite.Checked)
{
bytData[0]++;
bytData[1]+=2;
if(bytData[0]>200)bytData[0]=0;
if(bytData[1]>200)bytData[1]=0;
MemDB.Write(bytData,0,16);
}
}
}
}
}
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Text;
usingSystem.Windows.Forms;
usingShareMemLib;
namespaceYFShareMem
{
publicpartialclassfrmShareMem:Form
{
ShareMemMemDB=newShareMem();
publicfrmShareMem()
{
InitializeComponent();
}
privatevoidbtnOpen_Click(objectsender,EventArgse)
{
if(MemDB.Init("YFMemTest",10240)!=0)
{
//初始化失败
MessageBox.Show("初始化失败");
}
else
{
btnOpen.Enabled=false;
chkWrite.Enabled=true;
tmrTime.Enabled=true;
}
}
privatevoidtmrTime_Tick(objectsender,EventArgse)
{
byte[]bytData=newbyte[16];
intintRet=MemDB.Read(refbytData,0,16);
lstData.Items.Clear();
if(intRet==0)
{
for(inti=0;i<16;i++)
{
lstData.Items.Add(bytData[i].ToString());
}
if(chkWrite.Checked)
{
bytData[0]++;
bytData[1]+=2;
if(bytData[0]>200)bytData[0]=0;
if(bytData[1]>200)bytData[1]=0;
MemDB.Write(bytData,0,16);
}
}
}
}
}