共享内存操作类(C#源码)

来源:互联网 发布:精通d3.js 源代码 编辑:程序博客网 时间:2024/05/16 09:09
2007年07月30日 21:55:00

VC++的共享内存操作代码实现起来相对比较容易,但是用C#语言来实现,就有一定难度,由于工作需要,把以前VC开发的共享内存代码要用C#实现,别说,还费了不少周折,毕竟C#操作API函数和地址指针不是那么直接,还好,总算完成了,效果还不错。

共享内存操作类:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace ShareMemLib
{
public class ShareMem
{
[DllImport(
"user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);

[DllImport(
"Kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, uint flProtect, uint dwMaxSizeHi, uint dwMaxSizeLow, string lpName);

[DllImport(
"Kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr OpenFileMapping(int dwDesiredAccess,[MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,string lpName);

[DllImport(
"Kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr MapViewOfFile(IntPtr hFileMapping,uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow,uint dwNumberOfBytesToMap);

[DllImport(
"Kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool UnmapViewOfFile(IntPtr pvBaseAddress);

[DllImport(
"Kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);

[DllImport(
"kernel32", EntryPoint="GetLastError")]
public static extern int GetLastError ();

const int ERROR_ALREADY_EXISTS = 183;

const int FILE_MAP_COPY = 0x0001;
const int FILE_MAP_WRITE = 0x0002;
const int FILE_MAP_READ = 0x0004;
const int FILE_MAP_ALL_ACCESS = 0x0002 | 0x0004;

const int PAGE_READONLY = 0x02;
const int PAGE_READWRITE = 0x04;
const int PAGE_WRITECOPY = 0x08;
const int PAGE_EXECUTE = 0x10;
const int PAGE_EXECUTE_READ = 0x20;
const int PAGE_EXECUTE_READWRITE = 0x40;

const int SEC_COMMIT = 0x8000000;
const int SEC_IMAGE = 0x1000000;
const int SEC_NOCACHE = 0x10000000;
const int SEC_RESERVE = 0x4000000;

const int INVALID_HANDLE_VALUE = -1;

IntPtr m_hSharedMemoryFile
= IntPtr.Zero;
IntPtr m_pwData
= IntPtr.Zero;
bool m_bAlreadyExist = false;
bool m_bInit = false;
long m_MemSize=0;

public ShareMem()
{
}
~ShareMem()
{
Close();
}

/// >summary<
/// 初始化共享内存
/// >/summary<
/// >param name="strName"<共享内存名称>/param<
/// >param name="lngSize"<共享内存大小>/param<
/// >returns<>/returns<
public int Init(string strName, long lngSize)
{
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;
return 2; //创建共享体失败
}
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);
return 3; //创建内存映射失败
}
else
{
m_bInit
= true;
if (m_bAlreadyExist == false)
{
//初始化
}
}
//----------------------------------------
}
else
{
return 1; //参数错误
}

return 0; //创建成功
}
/// >summary<
/// 关闭共享内存
/// >/summary<
public void Close()
{
if (m_bInit)
{
UnmapViewOfFile(m_pwData);
CloseHandle(m_hSharedMemoryFile);
}
}

/// >summary<
/// 读数据
/// >/summary<
/// >param name="bytData"<数据>/param<
/// >param name="lngAddr"<起始地址>/param<
/// >param name="lngSize"<个数>/param<
/// >returns<>/returns<
public int Read(ref byte[] bytData, int lngAddr, int lngSize)
{
if (lngAddr + lngSize < m_MemSize) return 2; //超出数据区
if (m_bInit)
{
Marshal.Copy(m_pwData, bytData, lngAddr, lngSize);
}
else
{
return 1; //共享内存未初始化
}
return 0; //读成功
}

/// >summary<
/// 写数据
/// >/summary<
/// >param name="bytData"<数据>/param<
/// >param name="lngAddr"<起始地址>/param<
/// >param name="lngSize"<个数>/param<
/// >returns<>/returns<
public int Write(byte[] bytData, int lngAddr, int lngSize)
{
if (lngAddr + lngSize < m_MemSize) return 2; //超出数据区
if (m_bInit)
{
Marshal.Copy(bytData, lngAddr, m_pwData, lngSize);
}
else
{
return 1; //共享内存未初始化
}
return 0; //写成功
}
}
}

测试例程:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ShareMemLib;

namespace YFShareMem
{
public partial class frmShareMem : Form
{
ShareMem MemDB
=new ShareMem();
public frmShareMem()
{
InitializeComponent();
}

private void btnOpen_Click(object sender, EventArgs e)
{
if (MemDB.Init("YFMemTest", 10240) != 0)
{
//初始化失败
MessageBox.Show("初始化失败");
}
else
{
btnOpen.Enabled
= false;
chkWrite.Enabled
= true;
tmrTime.Enabled
= true;
}
}

private void tmrTime_Tick(object sender, EventArgs e)
{
byte[] bytData = new byte[16];
int intRet = MemDB.Read(ref bytData, 0, 16);
lstData.Items.Clear();
if (intRet == 0)
{
for (int i = 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);
}
}
}

}
}



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1717458


原创粉丝点击